home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / shells / cshel510 / part05 < prev    next >
Encoding:
Internet Message Format  |  1991-04-16  |  67.1 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i092: CShell 5.10 - alternative command interface, Part05/06
  4. Reply-To: umueller@iiic.ethz.ch
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i092@ab20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v91i088@ab20.larc.nasa.gov>
  8. Date: 16 Apr 91 19:34:38 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga.misc
  12.  
  13. Submitted-by: umueller@iiic.ethz.ch
  14. Posting-number: Volume 91, Issue 092
  15. Archive-name: shells/cshell-5.10/part05
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 5 (of 6)."
  24. # Contents:  comm1.c comm2.c
  25. # Wrapped by tadguy@ab20 on Tue Apr 16 15:34:35 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'comm1.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'comm1.c'\"
  29. else
  30. echo shar: Extracting \"'comm1.c'\" \(34186 characters\)
  31. sed "s/^X//" >'comm1.c' <<'END_OF_FILE'
  32. X/*
  33. X * COMM1.C
  34. X *
  35. X * Matthew Dillon, August 1986
  36. X *
  37. X * Version 2.07M by Steve Drew 10-Sep-87
  38. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  39. X * Version 5.00L by Urban Mueller 17-Feb-91
  40. X *
  41. X */
  42. X
  43. X#include "shell.h"
  44. X
  45. X/* comm1.c */
  46. Xstatic void display_file(char *filestr);
  47. Xstatic int search_file(char *s);
  48. Xstatic int quicksearch(char *name, int nocasedep, char *pattern);
  49. Xstatic int rm_file(char *file);
  50. Xstatic void setsystemtime(struct DateStamp *ds);
  51. Xstatic int found( char *lstart, int lnum, int loffs, char *name, char left );
  52. Xstatic void recurse(char *name, int (*action)(char *));
  53. Xstatic void recurse2( char *name, void (*action)(FIB *));
  54. Xstatic void lformat( char *s, char *d, struct file_info *info );
  55. X
  56. Xextern int has_wild;
  57. X
  58. Xint
  59. Xdo_sleep( void )
  60. X{
  61. X    int i;
  62. X
  63. X    if (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i--) Delay(50);
  64. X    return 0;
  65. X}
  66. X
  67. Xint
  68. Xdo_protect( void )
  69. X{
  70. X    static char flags[]="DEWRAPSH";
  71. X    char *s, *p;
  72. X    long setmask=0, clrmask=0xFF, mask;
  73. X    int  i, mode=0, stat;
  74. X    struct DPTR *dp;
  75. X
  76. X    for (s=strupr(av[--ac]); *s; s++) {
  77. X        if (*s=='=') { mode=0; continue; }
  78. X        if (*s=='+') { mode=1; clrmask=FIBF_ARCHIVE; continue; }
  79. X        if (*s=='-') { mode=2; clrmask=FIBF_ARCHIVE; continue; }
  80. X
  81. X        if (p=index(flags, *s)) {
  82. X            if( mode==0 ) setmask|= 1<<(p-flags), clrmask=0xFF;
  83. X            if( mode==1 ) setmask|= 1<<(p-flags);
  84. X            if( mode==2 ) clrmask|= 1<<(p-flags);
  85. X        } else
  86. X            ierror(av[ac],500);
  87. X    }
  88. X
  89. X    for (i=1; i<ac; i++) {
  90. X        if( (dp=dopen(av[i],&stat))) {
  91. X            mask = dp->fib->fib_Protection ^ 0x0F;
  92. X            mask&=~clrmask;
  93. X            mask|= setmask;
  94. X            dclose(dp);
  95. X            if( !SetProtection( av[i], mask ^ 0x0F))
  96. X                pError(av[i]);
  97. X        } else
  98. X            pError(av[i]);
  99. X    }
  100. X    return 0;
  101. X}
  102. X
  103. Xint
  104. Xdo_filenote( void )
  105. X{
  106. X    struct DPTR *dp;
  107. X    char *note;
  108. X    int i, stat;
  109. X
  110. X    if( options&1 ) {
  111. X        for( i=1; i<ac && !dobreak(); i++ )
  112. X            if( dp=dopen( av[i], &stat )) {
  113. X                printf( "%-12s %s\n", av[i],dp->fib->fib_Comment );
  114. X                dclose( dp );
  115. X            }
  116. X    } else {
  117. X        note=av[--ac];
  118. X        for (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
  119. X    }
  120. X    return 0;
  121. X}
  122. X
  123. Xint
  124. Xdo_cat( void )
  125. X{
  126. X    FILE *fi;
  127. X    int lctr, i, docr=0;
  128. X    char buf[256], *l;
  129. X
  130. X    prepscroll(0);
  131. X    if (ac<=1) {
  132. X        if (has_wild) { printf("No files matching\n"); return 20; }
  133. X        lctr=0;
  134. X        while (fgets(buf,256,stdin) && !dobreak()) {
  135. X            if (options) printf("%4d ",++lctr);
  136. X            quickscroll();
  137. X            l=buf+strlen( buf )-1; docr=1;
  138. X            if( l>=buf && *l=='\n' ) docr=0;
  139. X            fputs(buf,stdout);
  140. X        }
  141. X    } else {
  142. X        for (i=1; i<ac; i++)
  143. X            if (fi = fopen (av[i], "r")) {
  144. X                lctr=0;
  145. X                while (fgets(buf,256,fi) && !dobreak()) {
  146. X                    if (options&1) printf("%4d ",++lctr);
  147. X                    quickscroll();
  148. X                    l=buf+strlen( buf )-1; docr=1;
  149. X                    if( l>=buf && *l=='\n' ) docr=0;
  150. X                    fputs(buf,stdout); fflush(stdout);
  151. X                }
  152. X                fclose (fi);
  153. X            } else
  154. X                pError(av[i]);
  155. X    }
  156. X    if( docr && IsInteractive(Output()))
  157. X        putchar('\n');
  158. X    return 0;
  159. X}
  160. X
  161. X
  162. Xvoid
  163. Xget_drives(char *buf)
  164. X{
  165. X    struct DirectoryEntry *de_head=NULL, *de;
  166. X
  167. X    buf[0]=0;
  168. X    AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  169. X    for(de=de_head; de; de=de->de_Next) {
  170. X        if( buf[0] )
  171. X            strcat( buf, "\240" );
  172. X        strcat( buf, de->de_Name );
  173. X    }
  174. X    FreeDAList(de_head);
  175. X}
  176. X
  177. Xstatic char infobuf[100];
  178. Xstatic char namebuf[12];
  179. X
  180. Xchar *
  181. Xdrive_name( char *name )
  182. X{
  183. X    struct DirectoryEntry *de_head=NULL, *de;
  184. X    struct MsgPort *proc=DeviceProc( name );
  185. X
  186. X    strcpy( namebuf, name );
  187. X    AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  188. X    for(de=de_head; de; de=de->de_Next)
  189. X        if( DeviceProc( de->de_Name) == proc ) 
  190. X            strcpy( namebuf, de->de_Name );
  191. X    FreeDAList(de_head);
  192. X
  193. X    return namebuf;
  194. X}
  195. X
  196. Xint
  197. Xdo_info( void )
  198. X{
  199. X    struct DirectoryEntry *de_head=NULL, *de;
  200. X    int i;
  201. X
  202. X    puts("Unit    Size  Bytes  Used Blk/Byt-Free Full Errs  Status    Name");
  203. X
  204. X    if( ac==1 ) {
  205. X        AddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
  206. X        for(de=de_head; de; de=de->de_Next)
  207. X            oneinfo( de->de_Name, 0);
  208. X        FreeDAList(de_head);
  209. X    } else {
  210. X        for( i=1; i<ac; i++ )
  211. X            oneinfo( drive_name( av[i] ), 0 );
  212. X    }
  213. X
  214. X    return 0;
  215. X}
  216. X
  217. Xchar *
  218. Xoneinfo( char *name, int mode )
  219. X{
  220. X    BPTR lock;
  221. X    struct InfoData *info;
  222. X    long size, free, freebl, blocks;
  223. X    char *p, buf[130], *state="          ";
  224. X    char *fmt="%s\240%s\240%d\240%d\240%d\240%s\240%d%%\240%d\240%s\240%s";
  225. X
  226. X    Myprocess->pr_WindowPtr = (APTR)(-1);
  227. X
  228. X    infobuf[0]=0;
  229. X    if( !name ) name="";
  230. X    strcpy(infobuf,"0");
  231. X    info=(struct InfoData *)SAllocMem(sizeof(struct InfoData),MEMF_PUBLIC);
  232. X    if (lock=Lock(name,ACCESS_READ)) {
  233. X        if (Info(lock, info)) {
  234. X            PathName(lock, buf, 128L);
  235. X            if (p=index(buf,':')) *p = '\0';
  236. X            size  = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock);
  237. X            freebl= (info->id_NumBlocks-info->id_NumBlocksUsed);
  238. X            free  = freebl * info->id_BytesPerBlock;
  239. X            switch(info->id_DiskState) {
  240. X                case ID_WRITE_PROTECTED: state="Read Only "; break;
  241. X                case ID_VALIDATED:       state="Read/Write"; break;
  242. X                case ID_VALIDATING:      state="Validating"; break;
  243. X            }
  244. X            blocks=info->id_NumBlocks;
  245. X            if( mode==0 ) fmt="%-7s%5s%6d%7d%7d %5s%4d%%%4d  %s %s\n";
  246. X            sprintf(infobuf,fmt,
  247. X                name,
  248. X                itok( size ),
  249. X                info->id_BytesPerBlock,
  250. X                info->id_NumBlocksUsed,
  251. X                freebl,
  252. X                itok( free ),
  253. X                (blocks) ? (info->id_NumBlocksUsed * 100)/blocks : 0,
  254. X                info->id_NumSoftErrors,
  255. X                state,
  256. X                buf);
  257. X            if( mode==2 ) sprintf( infobuf, "%d", free );
  258. X            if( mode==3 ) sprintf( infobuf, "%d", freebl );
  259. X            if( mode==4 ) sprintf( infobuf, "%s", itok( free ));
  260. X            if( mode==5 ) sprintf( infobuf, "%s", buf );
  261. X        } else
  262. X            pError (name);
  263. X        UnLock(lock);
  264. X    } else {
  265. X        if     ( mode==1 ) sprintf( infobuf, "%s\240No disk present", name );
  266. X        else if( mode==0 ) sprintf( infobuf, "%-7s No disk present\n",name);
  267. X        else if( mode==5 ) sprintf( infobuf, ""  );
  268. X        else               sprintf( infobuf, "0" );
  269. X    }
  270. X    if( mode==0 ) printf( "%s",infobuf);
  271. X    FreeMem(info,sizeof(struct InfoData));
  272. X
  273. X    Myprocess->pr_WindowPtr = (APTR) o_noreq;
  274. X
  275. X    return infobuf;
  276. X}
  277. X
  278. X
  279. X/* things shared with display_file */
  280. X
  281. X#define DIR_SHORT 0x1
  282. X#define DIR_FILES 0x2
  283. X#define DIR_DIRS  0x4
  284. X#define DIR_NOCOL 0x8
  285. X#define DIR_NAMES 0x10
  286. X#define DIR_HIDE  0x20
  287. X#define DIR_LEN   0x40
  288. X#define DIR_TIME  0x80
  289. X#define DIR_BACK  0x100
  290. X#define DIR_UNIQ  0x200
  291. X#define DIR_IDENT 0x400
  292. X#define DIR_CLASS 0x800
  293. X#define DIR_QUIET 0x1000
  294. X#define DIR_AGE   0x2000
  295. X#define DIR_VIEW  0x4000
  296. X#define DIR_NOTE  0x8000
  297. X#define DIR_PATH  0x10000
  298. X#define DIR_LFORM 0x20000
  299. X#define DIR_BOT   0x40000
  300. X#define DIR_TOP   0x80000
  301. X
  302. Xstatic BPTR lastlock;
  303. Xstatic int filecount, col, colw, wwidth;
  304. Xstatic long bytes, blocks;
  305. X
  306. X/* the args passed to do_dir will never be expanded */
  307. X
  308. Xextern expand_err;
  309. Xextern int w_width;
  310. X
  311. Xstatic struct DateStamp Stamp;
  312. Xstatic char *LineBuf, *LinePos, LastWasDir, *LFormat, _LFormat[80], NoTitles;
  313. X
  314. Xint
  315. Xdo_dir( void )
  316. X{
  317. X    int i=1, c, eac, reverse, nump=ac, retcode=0;
  318. X    char **eav=NULL, **av1=NULL, **av2=NULL, inter=interactive();
  319. X    char linebuf[200];
  320. X    int (*func)(), ac1, ac2, factor=0;
  321. X
  322. X    LineBuf=LinePos=linebuf;
  323. X    LastWasDir=NoTitles=0;
  324. X    colw=-1;
  325. X
  326. X    LFormat=_LFormat;
  327. X
  328. X    if( options&DIR_CLASS ) options|=DIR_IDENT;
  329. X    if( !(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
  330. X
  331. X    DateStamp( &Stamp );
  332. X
  333. X    col = filecount = bytes = blocks = 0L;
  334. X    lastlock=0;
  335. X
  336. X    wwidth=77;
  337. X    if( inter ) printf( "\033[?7l" ), wwidth=w_width; /* end of line wrap off */
  338. X
  339. X    if( options&DIR_SHORT )
  340. X        strcpy(LFormat," %-18n%19m");
  341. X    else if( options&DIR_PATH )
  342. X        strcpy(LFormat," %-50p %7s %d"), NoTitles=1;
  343. X    else {
  344. X        if( options&DIR_NOTE )
  345. X            strcpy(LFormat,"   %-24n %o");
  346. X        else {
  347. X            strcpy(LFormat,"   %-24n %c%f ");
  348. X            if( options&DIR_VIEW )
  349. X                strcat(LFormat,"%10v ");
  350. X            else 
  351. X                strcat(LFormat,"%7s ");
  352. X            if( !(options&DIR_QUIET) )
  353. X                strcat(LFormat,options&DIR_VIEW?"%5b ":"%4b ");
  354. X            if( options&DIR_IDENT )
  355. X                strcat(LFormat,"%k");
  356. X            else if( options&DIR_AGE )
  357. X                strcat(LFormat,"%a");
  358. X            else 
  359. X                strcat(LFormat,"%d %t");
  360. X        }
  361. X    }
  362. X
  363. X    if( options&DIR_LFORM )
  364. X        if( ac>1 )
  365. X            LFormat=av[i++];
  366. X        else { 
  367. X            show_usage(NULL);
  368. X            return 20;
  369. X        }
  370. X
  371. X    if( ac == i) ++nump, av[i]="";
  372. X    if( options&DIR_UNIQ) {
  373. X        if( ac-i!=2 )  { show_usage(NULL); return 20; }
  374. X        i=0, nump=3;
  375. X    }
  376. X
  377. X    prepscroll(0);
  378. X    for( ; i<nump && !CHECKBREAK(); ++i ) {
  379. X        if( options&DIR_UNIQ ) {
  380. X            switch( i ) {
  381. X                case 0: av1=expand( av[ac-2], &ac1 );
  382. X                        av2=expand( av[ac-1], &ac2 );
  383. X                        eav=without( av1, ac1, av2, ac2, &eac, 1 );
  384. X                        break;
  385. X                case 1: printf("\nCommon files\n");
  386. X                        eav=and( av1, ac1, av2, ac2, &eac, 1 );
  387. X                        break;
  388. X                case 2: printf("\n");
  389. X                        eav=without( av2, ac2, av1, ac1, &eac, 1 );
  390. X                        break;
  391. X            }
  392. X            col = filecount = bytes = blocks = 0L;
  393. X            if (lastlock) UnLock(lastlock), lastlock=0;
  394. X        } else if (!(eav = expand(av[i], &eac)) && IoError) {
  395. X            ierror(av[i],IoError);
  396. X            retcode=5;
  397. X            continue;
  398. X        }
  399. X
  400. X        reverse= ( options&DIR_BACK ) ? 1 : 0;
  401. X        func=cmp;
  402. X        if( options & DIR_TIME) func=datecmp;
  403. X        if( options & DIR_LEN ) func=sizecmp;
  404. X        if( options & DIR_CLASS)func=classcmp;
  405. X        if( options & DIR_BOT ) factor=-99999999;
  406. X        if( options & DIR_TOP ) factor= 99999999;
  407. X        DirQuickSort(eav, eac, func, reverse, factor);
  408. X        for(c=0; c<eac && !CHECKBREAK(); ++c) {
  409. X            if( options & DIR_HIDE ) {
  410. X                char *b=BaseName(eav[c]);
  411. X                int  l=strlen(b)-5;
  412. X                struct file_info *info =
  413. X                    (struct file_info *)(eav[c]-sizeof(struct file_info));
  414. X                if(*b=='.'|| (l>=0 && !strcmp(b+l,".info"))||(info->flags&128))
  415. X                    continue;
  416. X            }
  417. X            if (options & DIR_NAMES)
  418. X                puts(eav[c]);
  419. X            else
  420. X                display_file(eav[c]);
  421. X        }
  422. X
  423. X        if (col) { quickscroll(); printf("%s\n",LinePos=LineBuf); col=0; }
  424. X
  425. X        if( LastWasDir )
  426. X            printf(o_lolite), LastWasDir=0;
  427. X
  428. X        if (options&DIR_UNIQ || (filecount>1 && i==nump-1)) {
  429. X            blocks += filecount; /* account for dir blocks */
  430. X            quickscroll();
  431. X            printf(" %ld Blocks, %s Bytes used in %d files\n",
  432. X                blocks, itoa(bytes), filecount);
  433. X        }
  434. X        if( options&DIR_UNIQ )
  435. X            free(eav);
  436. X        else 
  437. X            free_expand (eav);
  438. X    }
  439. X    if (lastlock) UnLock(lastlock), lastlock=0;
  440. X
  441. X    if( options&DIR_UNIQ )
  442. X        free_expand( av1 ), free_expand( av2 );
  443. X
  444. X    if( inter ) printf( "\033[?7h" );                /* end of line wrap off */
  445. X
  446. X    return retcode;
  447. X}
  448. X
  449. Xstatic int MultiCol=-1;
  450. X
  451. Xstatic void
  452. Xdisplay_file( char *filestr )
  453. X{
  454. X    int isadir, len, collen;
  455. X    char sc, *base, buf[130], *hilite;
  456. X    struct file_info *info;
  457. X    BPTR thislock;
  458. X
  459. X    base=BaseName(filestr);
  460. X    sc = *base;
  461. X    *base = '\0';
  462. X    thislock=Lock(filestr,SHARED_LOCK);
  463. X    /* if (thislock==NULL) return; */
  464. X    if( !NoTitles && (lastlock==NULL || CompareLock(thislock,lastlock))) {
  465. X        /* struct InfoData *id=AllocMem( sizeof(struct InfoData), 0); */
  466. X        if (col) { quickscroll(); printf("%s\n",LinePos=LineBuf); col=0; }
  467. X        quickscroll();
  468. X        PathName(thislock, buf, 128L);
  469. X        /* Info( thislock, id ); */
  470. X        if( LastWasDir )
  471. X            printf(o_lolite), LastWasDir=0;
  472. X        printf("Directory of %s\n", buf );
  473. X        /*itok((id->id_NumBlocks-id->id_NumBlocksUsed)*id->id_BytesPerBlock));*/
  474. X        /* FreeMem( id, sizeof(struct InfoData)); */
  475. X        if (lastlock) UnLock(lastlock);
  476. X        lastlock=thislock;
  477. X    } else
  478. X        UnLock(thislock);
  479. X    *base    = sc;
  480. X
  481. X    info   = (struct file_info *)(filestr - sizeof(struct file_info));
  482. X    isadir = info->size<0;
  483. X
  484. X    if((!(options & DIR_FILES) || isadir) && (!(options & DIR_DIRS) || !isadir))
  485. X        return;
  486. X
  487. X    hilite="";
  488. X    if (isadir!=LastWasDir && !(options & DIR_NOCOL)) 
  489. X        hilite=isadir ? o_hilite : o_lolite, LastWasDir=isadir;
  490. X
  491. X    lformat(LFormat, buf, info);
  492. X
  493. X    if( MultiCol==-1 ) {
  494. X        quickscroll();
  495. X        printf("%s%s",hilite,buf);
  496. X    } else {
  497. X        len=strlen(buf);
  498. X        if( col+len>wwidth ) {
  499. X            quickscroll();
  500. X            printf("%s\n",LineBuf);
  501. X            LinePos=LineBuf; col=0;
  502. X        }
  503. X        if( MultiCol )
  504. X            colw=MultiCol;
  505. X        else if( colw==-1 )
  506. X            colw=len;
  507. X        collen= (len+colw-1)-(len+colw-1)%colw;
  508. X        col+=collen;
  509. X        LinePos+=sprintf(LinePos,"%s%-*s",hilite,collen,buf);
  510. X    }
  511. X
  512. X    if(info->size>0)
  513. X        bytes  += info->size;
  514. X    blocks += info->blocks;
  515. X    filecount++;
  516. X}
  517. X
  518. X/* will have either of these formats:
  519. X *
  520. X *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
  521. X *    fullfilename'\0'hsparwed NNNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
  522. X *                              1111111111222222222233333333334 4  4
  523. X *                    01234567890123456789012345678901234567890 1  2
  524. X */
  525. X
  526. Xstatic char linebuf[140];
  527. Xstatic long dlen, dblocks;
  528. X
  529. Xstatic void
  530. Xcount( FIB *fib )
  531. X{
  532. X    dlen+=fib->fib_Size;
  533. X    dblocks+=fib->fib_NumBlocks+1;
  534. X}
  535. X
  536. Xstatic void
  537. Xlformat( char *s, char *d, struct file_info *info )
  538. X{
  539. X    long mi=0;
  540. X    char buf[120], *w, *t, *class;
  541. X    struct DPTR *dp;
  542. X    int stat, i, form, sign, cut, size=info->size;
  543. X    char *(*func)(int num);
  544. X
  545. X    MultiCol=-1;
  546. X    while( *s ) {
  547. X        if( *s!='%' ) { *d++=*s++; continue; }
  548. X        sign=1; form=0; cut=0; s++;
  549. X        if( *s=='-' ) s++, sign=-1;
  550. X        if( *s=='.' ) s++, cut=1;
  551. X        while( *s>='0' && *s<='9' ) form=10*form+*s++-'0';
  552. X        w=buf; *w=0;
  553. X        switch( *s ) {
  554. X        case 'p': strcpy(w,(char *)(info+1));             break;
  555. X        case 'b': sprintf(w,size>=0 ? "%d":"", info->blocks); break;
  556. X        case 's': sprintf(w,size>=0 ? "%d":"<Dir>",size); break;
  557. X        case 'i': *w++= size>=0 ? '-' : 'd'; *w=0;        break;
  558. X        case 'r': 
  559. X        case 'u':
  560. X            func= *s=='r' ? itoa : itok;
  561. X            strcpy( w,size>=0 ? (*func)(size) : "<Dir>");
  562. X            break;
  563. X        case 'n': 
  564. X        case 'q':
  565. X            strcpy(w,BaseName((char *)(info+1)));
  566. X            if( *s=='q' && size<0 ) strcat(w,"/");
  567. X            break;
  568. X        case 'c':
  569. X            *w++= info->flags & 1<<30 ? 'c' : '-'; *w=0;
  570. X            break;
  571. X        case 'f':
  572. X            for (i=7; i>=0; i--)
  573. X                *w++ = (info->flags^15) & (1L<<i) ? "hsparwed"[7-i] : '-';
  574. X            *w=0;
  575. X            break;
  576. X        case 'a': 
  577. X            if( Stamp.ds_Days!=0 ) {
  578. X                mi =Stamp.ds_Days*1440 + Stamp.ds_Minute;
  579. X                mi-=info->date.ds_Days*1440 + info->date.ds_Minute;
  580. X            }
  581. X            sprintf(w,mi>=0?"%4d days %02d:%02d":"Future    ",
  582. X                      mi/1440,mi/60%60,mi%60);
  583. X            break;
  584. X        case 'o':
  585. X            if( dp=dopen( (char *)(info+1), &stat )) {
  586. X                strcpy( w, dp->fib->fib_Comment );
  587. X                dclose( dp );
  588. X            }
  589. X            break;
  590. X        case 'v':
  591. X        case 'w':
  592. X            func= *s=='v' ? itoa : itok;
  593. X            dlen=dblocks=0;
  594. X            if( size<0 ) {
  595. X                recurse2( (char *)(info+1),count);
  596. X                strcpy( w, (*func)(dlen));
  597. X                size=dlen; info->blocks=dblocks;
  598. X            } else 
  599. X                strcpy( w, (*func)(size));
  600. X            break;
  601. X        case 'k':
  602. X            if( *info->class!=1 )
  603. X                strcpy(w,info->class);
  604. X            else if( class=getclass((char *)(info+1)))
  605. X                if( w=index(strncpy(w,class,50),0xA0) )
  606. X                    *w=0;
  607. X            break;
  608. X        case 'x':
  609. X        case 'd':
  610. X            sprintf(w,"%9s",dates(&info->date,*s=='x'));
  611. X            if(t=index(w,' ')) *t=0;
  612. X            break;
  613. X        case 't': sprintf(w,"%8s", next_word(dates(&info->date,0))); break;
  614. X        case 'm': MultiCol=form; form=0;      break;
  615. X        case '%': *w++=*++s; *w=0;            break;
  616. X        default : *w++='%';  *w++=*++s; *w=0; break;
  617. X        }
  618. X        if( cut ) buf[form]=0;
  619. X        *d=0; s++;
  620. X        d+=sprintf(d,sign<0?"%-*s":"%*s",form,buf);
  621. X    }
  622. X    if( MultiCol==-1 ) { *d++='\n'; }
  623. X    *d=0;
  624. X}
  625. X
  626. X
  627. X
  628. Xint
  629. Xdo_quit( void )
  630. X{
  631. X    if (Src_stack) {
  632. X        Quit = 1;
  633. X        return(do_return());
  634. X    }
  635. X    main_exit(0);
  636. X    return 0;
  637. X}
  638. X
  639. Xint
  640. Xdo_echo( void )
  641. X{
  642. X    char *args=compile_av(av,1,ac,' ',0);
  643. X    fprintf( (options&2)?stderr:stdout, (options&1)?"%s":"%s\n",args );
  644. X    free(args);
  645. X    return 0;
  646. X}
  647. X
  648. X
  649. Xstatic int
  650. Xbreakcheckd(void)
  651. X{
  652. X    int ret=!o_nobreak && SetSignal(0L,0L) & SIGBREAKF_CTRL_D;
  653. X    SetSignal(0L, SIGBREAKF_CTRL_D);
  654. X    if( ret )
  655. X        fprintf(stderr,"^D\n");
  656. X    return ret;
  657. X}
  658. X
  659. X/* gets a line from file, joining lines if they end in '\' */
  660. X
  661. X#define MAXLINE 512
  662. X
  663. Xstatic int
  664. Xsrcgets(char **buf, int *buflen, FILE *file)
  665. X{
  666. X    char *bufptr=*buf, *new, concat=0, cont;
  667. X    int   totlen=0;
  668. X
  669. X    do {
  670. X        if( totlen+MAXLINE > *buflen ) {
  671. X            new=salloc(*buflen *= 2);
  672. X            memcpy( new, *buf, 1+bufptr-*buf );
  673. X            bufptr+= new-*buf;
  674. X            free(*buf);
  675. X            *buf=new;
  676. X        }
  677. X        if (fgets(bufptr, MAXLINE, file)==NULL) {
  678. X            if( concat )
  679. X                fprintf(stderr,"Source: missing '}'\n");
  680. X            else if (bufptr != *buf)
  681. X                fprintf(stderr,"Source: file ends in '\\'\n");
  682. X            return -1;
  683. X        }
  684. X        totlen+=strlen(bufptr);
  685. X
  686. X        cont=0;
  687. X        bufptr+=strlen(bufptr)-1;
  688. X        if( *bufptr=='\n') *bufptr--=0;
  689. X        if( *bufptr=='\\') *bufptr--=0, cont=1;
  690. X        else if( *bufptr=='{' ) concat++;
  691. X        else if( *bufptr=='}' ) {
  692. X            if( concat>0 ) {
  693. X                concat--;
  694. X                if( concat ) *++bufptr=';';
  695. X            } else {
  696. X                fprintf(stderr,"Source: unexpected '}'\n");
  697. X                return -1;
  698. X            }
  699. X        } else if( concat ) *++bufptr=';';
  700. X        bufptr++;
  701. X    } while( cont || concat );
  702. X    *bufptr=0;
  703. X    return totlen;
  704. X}
  705. X
  706. X
  707. X
  708. Xint
  709. Xdo_source( char *str )
  710. X{
  711. X    FILE *fi;
  712. X    char *buf;
  713. X    ROOT *root;
  714. X    int  retcode, len, bufsize=512+MAXLINE;
  715. X
  716. X    if (Src_stack == MAXSRC) {
  717. X        ierror(NULL,217);
  718. X        return -1;
  719. X    }
  720. X
  721. X    if ((fi = fopen (av[1], "r")) == 0)
  722. X        { pError(av[1]); return -1;    }
  723. X
  724. X    push_locals(root=(ROOT *)salloc( sizeof(ROOT)));
  725. X    buf=salloc(bufsize);
  726. X
  727. X    set_var(LEVEL_SET, v_passed, next_word(next_word(str)));
  728. X    Src_pos  [Src_stack] = 0;
  729. X    Src_abort[Src_stack] = 0;
  730. X    Src_base [Src_stack] = fi;
  731. X    Src_if[Src_stack]=If_stack;
  732. X    ++Src_stack;
  733. X    while ((len=srcgets(&buf, &bufsize, fi))>=0&& !dobreak()&& !breakcheckd()){
  734. X        Src_pos[Src_stack-1] += len;
  735. X        if (Verbose&VERBOSE_SOURCE && !forward_goto)
  736. X            if( Verbose&VERBOSE_HILITE )
  737. X                fprintf(stderr,"%s)%s%s\n",o_hilite,buf,o_lolite);
  738. X            else 
  739. X                fprintf(stderr,")%s\n",buf);
  740. X        retcode=execute(buf);
  741. X        if( Src_abort[Src_stack-1] ) break; else retcode=0;
  742. X    }
  743. X    --Src_stack;
  744. X    if( If_stack>Src_if[Src_stack] )
  745. X        If_stack=Src_if[Src_stack], disable=If_stack && If_base[If_stack-1];
  746. X
  747. X    if (forward_goto) ierror(NULL,501);
  748. X    forward_goto = 0;
  749. X    unset_level(LEVEL_SOURCE + Src_stack);
  750. X    unset_var(LEVEL_SET, v_gotofwd);
  751. X    unset_var(LEVEL_SET, v_passed);
  752. X    fclose (fi);
  753. X
  754. X    pop_locals();
  755. X    free(buf);
  756. X    free(root);
  757. X
  758. X    return retcode;
  759. X}
  760. X
  761. X/* set process cwd name and $_cwd, if str != NULL also print it. */
  762. X
  763. Xint
  764. Xdo_pwd( char *str )
  765. X{
  766. X    char pwd[130];
  767. X
  768. X    PathName(Myprocess->pr_CurrentDir, pwd, 128L);
  769. X    if (str) puts(pwd);
  770. X    set_var(LEVEL_SET, v_cwd, pwd);
  771. X    /* put the current dir name in our CLI task structure */
  772. X    CtoBStr(pwd, Mycli->cli_SetName, 128L);
  773. X    return 0;
  774. X}
  775. X
  776. X/*
  777. X * CD
  778. X *
  779. X * CD(str, 0)      -do CD operation.
  780. X *
  781. X */
  782. X
  783. Xextern int qcd_flag;
  784. X
  785. Xstatic char lastqcd[80];
  786. Xstatic lastoffs;
  787. X
  788. Xint
  789. Xdo_cd( char *str )
  790. X{
  791. X    BPTR oldlock, filelock;
  792. X    FILE *file;
  793. X    char buf[100], *old;
  794. X    int  i=1, repeat;
  795. X
  796. X    if( options & 1 ) {
  797. X        if( !(file=fopen( o_csh_qcd, "w" )))
  798. X            { fprintf(stderr,"Can't open output\n"); return 20; }
  799. X        for( ; i<ac && !breakcheck(); i++ ) {
  800. X            fprintf(file,"%s\n",av[i]);
  801. X            strcpy(buf,av[i]);
  802. X            appendslash( buf );
  803. X            expand_all( buf, file );
  804. X        }
  805. X        fclose(file);
  806. X        return 0;
  807. X    }
  808. X
  809. X    str= ( has_wild && ac>=2 ) ? av[1] : next_word(str);
  810. X    if (!strcmp("..",str)) str="/";
  811. X
  812. X    if( !*str ) {
  813. X        printf("%s\n", get_var( LEVEL_SET, v_cwd ));
  814. X        return 0;
  815. X    }
  816. X
  817. X    if (filelock=Lock(str,ACCESS_READ)) {
  818. X        lastqcd[0]=0;
  819. X        if (!isdir(str)) { UnLock(filelock); ierror(str,212); return 20; }
  820. X    } else {
  821. X        repeat= !strncmp( lastqcd, str, 79 );
  822. X        strncpy( lastqcd, str, 79);
  823. X
  824. X        if( !quick_cd( buf, av[i], repeat) )
  825. X            { fprintf(stderr,"Object not found %s\n",str); return 20; }
  826. X        if (!(filelock=Lock(buf,ACCESS_READ))) 
  827. X            { pError(buf); return 20; }
  828. X    }
  829. X    if (oldlock=CurrentDir(filelock)) UnLock(oldlock);
  830. X    if( !(old=get_var(LEVEL_SET, v_cwd)) )
  831. X        old="";
  832. X    set_var(LEVEL_SET, v_lcd, old);
  833. X    do_pwd(NULL);
  834. X
  835. X    return 0;
  836. X}
  837. X
  838. Xchar *
  839. Xquick_cd( char *buf, char *name, int repeat )
  840. X{
  841. X    qcd_flag=repeat ? 2 : 1;
  842. X    strcpy(buf,name);
  843. X    if( quicksearch( o_csh_qcd, 1, buf)!=2 )
  844. X        return NULL;
  845. X    return buf;
  846. X}
  847. X
  848. X
  849. Xint
  850. Xdo_mkdir( void )
  851. X{
  852. X    int i;
  853. X    BPTR lock;
  854. X    
  855. X    for (i=1; i<ac; ++i) {
  856. X        if (exists(av[i]))
  857. X            ierror(av[i],203);
  858. X        else if (lock=CreateDir(av[i]))
  859. X            UnLock (lock);
  860. X        else
  861. X            pError(av[i]);
  862. X    }
  863. X    return 0;
  864. X}
  865. X
  866. Xint
  867. Xdo_mv( void )
  868. X{
  869. X    char *dest, buf[256];
  870. X    int dirflag, i;
  871. X
  872. X    dirflag=isdir(dest=av[--ac]);
  873. X    if (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
  874. X    for (i=1; i<ac; ++i) {
  875. X        strcpy(buf, dest);
  876. X        if (dirflag) TackOn(buf, BaseName(av[i]));
  877. X        if (Rename(av[i], buf)==0)
  878. X            { pError(av[i]); return -1; }
  879. X        else 
  880. X            clear_archive_bit( buf );
  881. X    }
  882. X    return 0;
  883. X}
  884. X
  885. Xstatic int dirstoo;
  886. X
  887. Xint
  888. Xall_args( int (*action)(char *str), int dirsflag )
  889. X{
  890. X    int i;
  891. X
  892. X    dirstoo=dirsflag;
  893. X    for ( i=1; i<ac && !dobreak(); ++i)
  894. X        if (isdir(av[i])) {
  895. X            if (options & 1) recurse(av[i], action);
  896. X            else if (dirstoo) (*action)(av[i]);
  897. X        } else
  898. X            (*action)(av[i]);
  899. X    return 0;
  900. X}
  901. X
  902. Xchar *searchstring;
  903. Xchar docr;
  904. X
  905. X#define SEARCH_REC   1
  906. X#define SEARCH_CASE  2
  907. X#define SEARCH_WILD  4
  908. X#define SEARCH_NUM   8
  909. X#define SEARCH_EXCL  16
  910. X#define SEARCH_QUIET 32
  911. X#define SEARCH_VERB  64
  912. X#define SEARCH_BIN   128
  913. X#define SEARCH_FILE  256
  914. X#define SEARCH_ABORT 512
  915. X#define SEARCH_LEFT  1024
  916. X#define SEARCH_ONLY  2048
  917. X
  918. Xstatic int abort_search;
  919. Xstatic char lowbuf[256], file_name, file_cr;
  920. X
  921. Xstatic int
  922. Xsearch_file( char *s )
  923. X{
  924. X    FILE *fi;
  925. X    char *p, *q;
  926. X    int nocasedep, lctr, len, excl=((options & 16) !=0 ), yesno;
  927. X    char buf[256], searchit[120], first, left;
  928. X
  929. X    if( abort_search )
  930. X        return 0;
  931. X
  932. X    nocasedep=!(options & SEARCH_CASE);
  933. X    lctr= docr= file_name= file_cr= 0;
  934. X    if (!(options & (SEARCH_QUIET|SEARCH_FILE)))
  935. X        if( options & SEARCH_VERB )
  936. X            printf("Examining %s...\n",s);
  937. X        else 
  938. X            printf("\015Examining %s...                  ",s), docr=1;
  939. X
  940. X    strcpy(searchit,searchstring);
  941. X    if (options & SEARCH_WILD) strcat(searchit,"\n");
  942. X    len=strlen(searchit);
  943. X    if (nocasedep) strupr(searchit);
  944. X    first=*searchit;
  945. X
  946. X    if( strcmp("STDIN",s) && !(options&SEARCH_WILD) && !excl ||
  947. X                 options&SEARCH_BIN )
  948. X        if( quicksearch(s,nocasedep,searchit) )
  949. X            return 0;
  950. X
  951. X    if( options&SEARCH_BIN )
  952. X        { fprintf(stderr,"Out of memory\n"); return 20; }
  953. X
  954. X    fi = strcmp("STDIN",s) ?  fopen(s,"r") : stdin;
  955. X    if (fi==NULL) { pError(s); return 20; }
  956. X
  957. X    prepscroll(0);
  958. X
  959. X    while (fgets(buf,256,fi) && !dobreak()) {
  960. X        lctr++; left=1;
  961. X        if (options & SEARCH_WILD)
  962. X            yesno=compare_ok(searchit, p=buf, options&SEARCH_CASE);
  963. X        else {
  964. X            if (nocasedep) {
  965. X                strcpy(lowbuf,buf);
  966. X                strupr(lowbuf);
  967. X                p=lowbuf;
  968. X            } else
  969. X                p=buf;
  970. X            q=p;
  971. X            while ((p=index(p,first)) && strncmp(p++,searchit,len)) ;
  972. X            yesno= (p!=NULL);
  973. X            left = --p - q;
  974. X        }
  975. X        if( yesno ^ excl )
  976. X            if(!(options&SEARCH_ONLY)|| !isalphanum(p[-1])&&!isalphanum(p[len]))
  977. X                if( found(buf, lctr, 0, s, left ) )
  978. X                    break;
  979. X    }
  980. X    if (fi!=stdin) fclose (fi);
  981. X    if( file_cr ) printf("\n");
  982. X    return 0;
  983. X}
  984. X
  985. Xint qcd_flag, qcd_offs;
  986. X
  987. Xstatic int
  988. Xquicksearch( char *name, int nocasedep, char *pattern )
  989. X{
  990. X    int i, ptrn=strlen(pattern);
  991. X    char ut[256], *buffer, *lend;
  992. X    char *uptab=ut, *get, c, *lpos, *lstart;
  993. X    int len, lnum, qcd=qcd_flag, repeat=(qcd==2 && qcd_offs!=0);
  994. X    int sofar, got;
  995. X    BPTR fh;
  996. X
  997. X#ifdef AZTEC_C
  998. X    while(0) while(0) c=c=0, uptab=uptab=ut, get=get=NULL;
  999. X#endif
  1000. X
  1001. X    qcd_flag=0;
  1002. X    if( !(fh=Open(name,MODE_OLDFILE))) { 
  1003. X        i=(long)IoErr(), docr=0;
  1004. X        printf("\n");
  1005. X        ierror(name,i);
  1006. X        return 1;
  1007. X    }
  1008. X    len=filesize( name );
  1009. X    if( !(buffer=(void *)malloc(len+2))) { Close(fh); return 0; }
  1010. X    sofar=0;
  1011. X    do {
  1012. X        got=Read( fh, (char *)buffer+sofar, 60000);
  1013. X        sofar+=got;
  1014. X    } while( got==60000 );
  1015. X    Close( fh);
  1016. X    if( sofar != len ) { pError(pattern); return 1; }
  1017. X
  1018. X    if( nocasedep )
  1019. X        strupr( pattern );
  1020. X
  1021. X    if( !qcd )
  1022. X        prepscroll(0);
  1023. X
  1024. X    for( i=0; i<256; i++ ) uptab[i]=i;
  1025. X    if( nocasedep ) for( i='a'; i<='z'; i++ ) uptab[i]=i-'a'+'A';
  1026. Xretry:
  1027. X    c=*pattern, buffer[len]=c, buffer[len+1]=c;
  1028. X    get= (qcd==2) ? buffer+qcd_offs : buffer;
  1029. X    if( qcd==1 ) qcd_offs=0;
  1030. X
  1031. X    lpos=lstart=buffer, lnum=1;
  1032. X    for( ;; ) {
  1033. X        do ; while( uptab[*get++]!=c );
  1034. X        if( --get>=buffer + len )
  1035. X            break;
  1036. X        for( i=1; i<ptrn; i++ )
  1037. X            if( uptab[get[i]]!=pattern[i] )
  1038. X                break;
  1039. X        if( i==ptrn ) {
  1040. X            for( ;lpos<get; lpos++ )
  1041. X                if( *lpos=='\n' )
  1042. X                    lstart=lpos+1, lnum++;
  1043. X            for( lend=lstart+1; *lend!='\n'; lend++ ) ;
  1044. X            if( qcd ) {
  1045. X                if( get[-1]==':' || get[-1]=='/' ||
  1046. X                      lpos==lstart && lend[-1]==':' ) {
  1047. X                    char *tmp;
  1048. X                    for( tmp=get+ptrn; *tmp&& *tmp!='\n'&& *tmp!='/'; tmp++ );
  1049. X                    if( *tmp!='/' ) {
  1050. X                        *lend=0;
  1051. X                        strncpy(pattern,lstart,79);
  1052. X                        qcd_offs=lend-buffer;
  1053. X                        free( buffer );
  1054. X                        return 2;
  1055. X                    }
  1056. X                } else 
  1057. X                    lend=lpos+1;
  1058. X            } else {
  1059. X                *lend=0;
  1060. X                if(!(options&SEARCH_ONLY) ||
  1061. X                     !isalphanum(lpos[-1])&&!isalphanum(lpos[ptrn]))
  1062. X                    if(found(lstart, lnum, get-buffer, name, lpos==lstart ))
  1063. X                        break;
  1064. X                *lend='\n';
  1065. X            }
  1066. X            get=lend+1;
  1067. X        } else
  1068. X            get++;
  1069. X    }
  1070. X    if( repeat )  { repeat=0; qcd_offs=0; goto retry; }
  1071. X    if( file_cr ) { printf("\n"); quickscroll(); }
  1072. X    free( buffer );
  1073. X    return 1;
  1074. X}
  1075. X
  1076. Xstatic int
  1077. Xfound( char *lstart, int lnum, int loffs, char *name, char left )
  1078. X{
  1079. X    int fileabort=0;
  1080. X
  1081. X    if( (options&SEARCH_LEFT) && !left)
  1082. X        return 0;
  1083. X
  1084. X    if ( docr )
  1085. X        { quickscroll(); printf("\n"); docr=0; }
  1086. X
  1087. X    if( options&SEARCH_FILE ) {
  1088. X        file_cr=1;
  1089. X        if( !file_name )
  1090. X            printf("%s",name), file_name=1;
  1091. X        if( options&SEARCH_NUM )
  1092. X            fileabort=1;
  1093. X        else 
  1094. X            printf(" %d",lnum);
  1095. X    } else if( options & SEARCH_BIN ) {
  1096. X        if (!(options & SEARCH_NUM))
  1097. X            printf("Byte offset %d\n",loffs);
  1098. X        else 
  1099. X            printf("%d\n",loffs);
  1100. X        quickscroll();
  1101. X    } else {
  1102. X        if (!(options & SEARCH_NUM))
  1103. X            printf("%4d ",lnum);
  1104. X        printf((lstart[strlen(lstart)-1]=='\n')?"%s":"%s\n",lstart);
  1105. X        quickscroll();
  1106. X    }
  1107. X    abort_search= options&SEARCH_ABORT;
  1108. X    return dobreak() || fileabort || abort_search;
  1109. X}
  1110. X
  1111. X
  1112. Xint
  1113. Xdo_search( void )
  1114. X{
  1115. X    if(!IsInteractive(Output())) options |= SEARCH_VERB;
  1116. X    abort_search=0;
  1117. X    searchstring=av[--ac];
  1118. X    all_args(search_file, 0);
  1119. X    if(docr) printf("\n"),docr=0;
  1120. X    return 0;
  1121. X}
  1122. X
  1123. Xstatic int
  1124. Xrm_file(char *file)
  1125. X{
  1126. X    if ( file[strlen(file)-1]=='/' ) file[strlen(file)-1]=0;
  1127. X    if (has_wild) printf(" %s...",file);
  1128. X    if (options & 2) SetProtection(file,0L);
  1129. X    if (!DeleteFile(file)) 
  1130. X        { pError (file); return 20; }
  1131. X    else if (has_wild)
  1132. X        printf("Deleted\n");
  1133. X    return 0;
  1134. X}
  1135. X
  1136. Xint
  1137. Xdo_rm( void )
  1138. X{
  1139. X    all_args( rm_file, 1);
  1140. X    return 0;
  1141. X}
  1142. X
  1143. Xchar *NameCopy;
  1144. Xint (*Action)(char *);
  1145. Xint Level;
  1146. X
  1147. Xstatic void
  1148. Xtrue_recurse( char *name )
  1149. X{
  1150. X    BPTR lock, cwd;
  1151. X    FIB *fib=(FIB *)SAllocMem((long)sizeof(FIB),MEMF_PUBLIC);
  1152. X
  1153. X    NameCopy[0]=0;
  1154. X    if (lock=Lock(name,ACCESS_READ)) {
  1155. X        cwd =CurrentDir(lock);
  1156. X        if (Examine(lock, fib))
  1157. X            while (ExNext(lock, fib) && !CHECKBREAK()) {
  1158. X                if (*NameCopy) { (*Action)(NameCopy); NameCopy[0]=0; }
  1159. X                if (fib->fib_DirEntryType==ST_USERDIR) {
  1160. X                    true_recurse(fib->fib_FileName);
  1161. X                    if (dirstoo) { strcpy(NameCopy,fib->fib_FileName); }
  1162. X                } else if( fib->fib_DirEntryType<0 )
  1163. X                    strcpy(NameCopy,fib->fib_FileName);
  1164. X            }
  1165. X        if (*NameCopy) { (*Action)(NameCopy); NameCopy[0]=0; }
  1166. X
  1167. X        UnLock(CurrentDir(cwd));
  1168. X    } else
  1169. X        pError(name);
  1170. X    FreeMem(fib, (long)sizeof(FIB));
  1171. X}
  1172. X
  1173. Xstatic void
  1174. Xrecurse(char *name, int (*action)(char *))
  1175. X{
  1176. X    NameCopy=salloc(256);
  1177. X    Action=action;
  1178. X    true_recurse( name );
  1179. X    if (dirstoo) { (*Action)(name); }
  1180. X    free(NameCopy);
  1181. X}
  1182. X
  1183. X
  1184. Xstatic void
  1185. Xrecurse2( char *name, void (*action)(FIB *))
  1186. X{
  1187. X    BPTR lock, cwd;
  1188. X    FIB  *fib=(FIB *)SAllocMem(sizeof(FIB),MEMF_PUBLIC);
  1189. X
  1190. X    if (lock=Lock(name,ACCESS_READ)) {
  1191. X        cwd =CurrentDir(lock);
  1192. X        if (Examine(lock, fib))
  1193. X            while (ExNext(lock, fib) && !CHECKBREAK()) {
  1194. X                (*action)(fib);
  1195. X                if (fib->fib_DirEntryType==ST_USERDIR)
  1196. X                    recurse2(fib->fib_FileName,action);
  1197. X            }
  1198. X        UnLock(CurrentDir(cwd));
  1199. X    }
  1200. X
  1201. X    FreeMem(fib, sizeof(FIB));
  1202. X}
  1203. X
  1204. X
  1205. Xint
  1206. Xdo_history( void )
  1207. X{
  1208. X    struct HIST *hist;
  1209. X    int i = H_tail_base;
  1210. X    int len = (av[1]) ? strlen(av[1]) : 0;
  1211. X
  1212. X    for (hist = H_tail; hist && !dobreak(); hist = hist->prev, i++)
  1213. X        if (len == 0 || !strncmp(av[1], hist->line, len))
  1214. X            printf("%3d %s\n", i, hist->line);
  1215. X    return 0;
  1216. X}
  1217. X
  1218. Xint
  1219. Xdo_mem( void )
  1220. X{
  1221. X    static long clast, flast;
  1222. X    long cfree, ffree;
  1223. X    char *desc="Free";
  1224. X
  1225. X    Forbid();
  1226. X    cfree = AvailMem (MEMF_CHIP);
  1227. X    ffree = AvailMem (MEMF_FAST);
  1228. X    Permit();
  1229. X    if( options&8 ) {
  1230. X        clast=cfree, flast=ffree;
  1231. X        return 0;
  1232. X    }
  1233. X    if( options&16 )
  1234. X        cfree=clast-cfree, ffree=flast-ffree, desc="Used";
  1235. X    if( options&4 ) {
  1236. X        if     ( options & 1 ) printf("%ld\n",cfree);
  1237. X        else if( options & 2 ) printf("%ld\n",ffree);
  1238. X        else                   printf("%ld\n",cfree+ffree);
  1239. X    } else {
  1240. X        if     ( options & 1 ) printf("Free CHIP memory:%10s\n",itoa(cfree));
  1241. X        else if( options & 2 ) printf("Free FAST memory:%10s\n",itoa(ffree));
  1242. X        else {
  1243. X            if(ffree) {
  1244. X                printf("FAST memory:%10s\n",itoa(ffree));
  1245. X                printf("CHIP memory:%10s\n",itoa(cfree));
  1246. X            }
  1247. X            printf("Total  %s:%10s\n",desc,itoa(cfree+ffree));
  1248. X        }
  1249. X    }
  1250. X    return 0;
  1251. X}
  1252. X
  1253. Xint
  1254. Xdo_forline( void )
  1255. X{
  1256. X    char vname[33], buf[256], *cstr;
  1257. X    int lctr;
  1258. X    FILE *f;
  1259. X
  1260. X    strcpy(vname,av[1]);
  1261. X    if( !strcmp(av[2],"STDIN") )
  1262. X        f=stdin;
  1263. X    else 
  1264. X        if(!(f=fopen(av[2],"r"))) { pError(av[2]); return 20; }
  1265. X
  1266. X    lctr=0;
  1267. X    ++H_stack;
  1268. X    cstr = compile_av (av, 3, ac, ' ', 0);
  1269. X    while (fgets(buf,256,f) && !dobreak()) {
  1270. X        buf[strlen(buf)-1]='\0';    /* remove CR */
  1271. X        lctr++;
  1272. X        set_var(LEVEL_SET, vname, buf);
  1273. X        sprintf(buf,"%d",lctr);
  1274. X        set_var(LEVEL_SET, v_linenum, buf);
  1275. X        exec_command(cstr);
  1276. X    }
  1277. X    if( f!=stdin ) fclose(f);
  1278. X    --H_stack;
  1279. X    free (cstr);
  1280. X    unset_var (LEVEL_SET, vname);
  1281. X    unset_var (LEVEL_SET, v_linenum);
  1282. X    return 0;
  1283. X}
  1284. X
  1285. Xint
  1286. Xdo_fornum( void )
  1287. X{
  1288. X    char vname[33], buf[16];
  1289. X    int n1, n2, step, i=1, verbose;
  1290. X    char *cstr;
  1291. X
  1292. X    verbose=(options & 1);
  1293. X    strcpy(vname,av[i++]);
  1294. X    n1=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  1295. X    n2=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  1296. X    if (options & 2) {
  1297. X        step=myatoi(av[i++],-32767,32767); if (atoierr) return 20;
  1298. X    } else
  1299. X        step=1;
  1300. X    ++H_stack;
  1301. X    cstr = compile_av (av, i, ac, ' ', 0);
  1302. X    for (i=n1; (step>=0 ? i<=n2 : i>=n2) && !CHECKBREAK(); i+=step) {
  1303. X        if (verbose) fprintf(stderr, "fornum: %d\n", i);
  1304. X        sprintf(buf,"%d",i);
  1305. X        set_var (LEVEL_SET, vname, buf);
  1306. X        exec_command(cstr);
  1307. X    }
  1308. X    --H_stack;
  1309. X    free (cstr);
  1310. X    unset_var (LEVEL_SET, vname);
  1311. X    return 0;
  1312. X}
  1313. X
  1314. X/*
  1315. X * foreach var_name  ( str str str str... str ) commands
  1316. X * spacing is important (unfortunately)
  1317. X *
  1318. X * ac=0    1 2 3 4 5 6 7
  1319. X * foreach i ( a b c ) echo $i
  1320. X * foreach i ( *.c ) "echo -n "file ->";echo $i"
  1321. X */
  1322. X
  1323. Xint
  1324. Xdo_foreach( void )
  1325. X{
  1326. X    int cstart, cend;
  1327. X    char *cstr, vname[33];
  1328. X    char **fav;
  1329. X    int i=1, verbose;
  1330. X
  1331. X    verbose=(options & 1);
  1332. X    strcpy(vname, av[i++]);
  1333. X    if (*av[i] == '(') i++;
  1334. X    cstart = i;
  1335. X    while (i<ac && *av[i] != ')') i++;
  1336. X    if (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
  1337. X    ++H_stack;
  1338. X    cend = i;
  1339. X
  1340. X    fav = (char **)salloc(sizeof(char *) * (ac));
  1341. X    for (i = cstart; i < cend; ++i) fav[i] = av[i];
  1342. X
  1343. X    cstr = compile_av (av, cend + 1, ac, ' ', 0);
  1344. X
  1345. X    for (i = cstart; i<cend && !CHECKBREAK(); ++i) {
  1346. X        set_var (LEVEL_SET, vname, fav[i]);
  1347. X        if (verbose) fprintf(stderr, "foreach: %s\n", fav[i]);
  1348. X        execute(cstr);
  1349. X    }
  1350. X    --H_stack;
  1351. X    free (fav);
  1352. X    free (cstr);
  1353. X    unset_var (LEVEL_SET, vname);
  1354. X    return 0;
  1355. X}
  1356. X
  1357. Xint
  1358. Xdo_forever( char *str )
  1359. X{
  1360. X    int rcode = 0;
  1361. X    char *ptr = next_word( str );
  1362. X
  1363. X    ++H_stack;
  1364. X    for (;;) {
  1365. X        if (CHECKBREAK()) { rcode = 20; break; }
  1366. X        if (exec_command (ptr) < 0) {
  1367. X            str = get_var(LEVEL_SET, v_lasterr);
  1368. X            rcode = (str) ? atoi(str) : 20;
  1369. X            break;
  1370. X        }
  1371. X    }
  1372. X    --H_stack;
  1373. X    return rcode;
  1374. X}
  1375. X
  1376. Xextern struct IntuitionBase *IntuitionBase;
  1377. X
  1378. Xint
  1379. Xdo_window( void )
  1380. X{
  1381. X    long x=-1, y=-1, w=-1, h=-1, maxwidth, maxheight, arg[5];
  1382. X    int i;
  1383. X
  1384. X    if(options & 32) {
  1385. X        struct Screen *scrn;
  1386. X        struct Window *window;
  1387. X        char buf[80];
  1388. X        buf[40]=0;
  1389. X        for (scrn=IntuitionBase->FirstScreen; scrn; scrn=scrn->NextScreen) {
  1390. X            buf[0]=0;
  1391. X            if( scrn->Title )
  1392. X                strncpy(buf,(char*)scrn->Title,40);
  1393. X            printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
  1394. X                buf,
  1395. X                scrn->LeftEdge,
  1396. X                scrn->TopEdge,
  1397. X                scrn->Width,
  1398. X                scrn->Height
  1399. X            );
  1400. X            for (window=scrn->FirstWindow; window; window=window->NextWindow) {
  1401. X                buf[0]=0;
  1402. X                if( window->Title )
  1403. X                    strncpy(buf,(char*)window->Title,40);
  1404. X                printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
  1405. X                    buf,
  1406. X                    window->LeftEdge,
  1407. X                    window->TopEdge,
  1408. X                    window->Width,
  1409. X                    window->Height
  1410. X                );
  1411. X            }
  1412. X        }
  1413. X        return 0;
  1414. X    }
  1415. X
  1416. X    if( o_nowindow || !Win )
  1417. X        return 20;
  1418. X
  1419. X    maxwidth = Win->WScreen->Width;
  1420. X    maxheight= Win->WScreen->Height;
  1421. X    if( options&1 )
  1422. X        x=Win->LeftEdge,y=Win->TopEdge,w=Win->MinWidth,h=Win->MinHeight;
  1423. X    if( options&2 ) x=y=0, w=maxwidth, h=maxheight;
  1424. X    if( options&4 ) WindowToFront(Win);
  1425. X    if( options&8 ) WindowToBack(Win);
  1426. X    if( options&16) ActivateWindow(Win);
  1427. X    if( ac >= 5) {
  1428. X        for(i=1; i<5; i++) {
  1429. X            arg[i] = myatoi(av[i],0,1023); if (atoierr) return 20;
  1430. X        }
  1431. X        x=arg[1]; y=arg[2]; w=arg[3]; h=arg[4];
  1432. X    }
  1433. X    if( w!=-1 ) {
  1434. X        int i;
  1435. X        if ( x+w>maxwidth || y+h>maxheight ) {
  1436. X            ierror(NULL, 500);
  1437. X            return 20;
  1438. X        }
  1439. X        if( w<Win->MinWidth  ) w=Win->MinWidth;
  1440. X        if( h<Win->MinHeight ) h=Win->MinHeight;
  1441. X        if( Win->LeftEdge!=0 || Win->TopEdge!=0 )
  1442. X            MoveWindow(Win, -Win->LeftEdge, -Win->TopEdge );
  1443. X        if( Win->Width!=w || Win->Height!=h )
  1444. X            SizeWindow(Win, w-Win->Width   , h-Win->Height  );
  1445. X        if( x || y )
  1446. X            MoveWindow(Win, x, y );
  1447. X        for( i=0; i<10; i++ ) {
  1448. X            if(  Win->LeftEdge==x && Win->TopEdge==y && 
  1449. X                 Win->Width   ==w && Win->Height ==h )
  1450. X                break;
  1451. X            Delay(5);
  1452. X        }
  1453. X    } else 
  1454. X        Delay(20); /* pause 1/2 sec. before trying to print */
  1455. X
  1456. X    printf("\014");
  1457. X    return 0;
  1458. X}
  1459. X
  1460. X
  1461. Xstatic void
  1462. Xsetsystemtime(struct DateStamp *ds)
  1463. X{
  1464. X    struct timerequest tr;
  1465. X    long secs= ds->ds_Days*86400+ds->ds_Minute*60+ds->ds_Tick/TICKS_PER_SECOND;
  1466. X
  1467. X    if (OpenDevice(TIMERNAME, UNIT_VBLANK,(struct IORequest *)&tr, 0L)) {
  1468. X        fprintf(stderr,"Clock error: can't open timer device\n");
  1469. X        return;
  1470. X    }
  1471. X
  1472. X    tr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  1473. X    tr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
  1474. X    tr.tr_node.io_Message.mn_Node.ln_Name = NULL;
  1475. X    tr.tr_node.io_Message.mn_ReplyPort = NULL;
  1476. X    tr.tr_node.io_Command = TR_SETSYSTIME;
  1477. X    tr.tr_time.tv_secs = secs;
  1478. X    tr.tr_time.tv_micro = 0L;
  1479. X    if (DoIO ((struct IORequest *)&tr))
  1480. X        fprintf(stderr,"Clock error: can't talk to timer device\n");
  1481. X    CloseDevice ((struct IORequest *)&tr);
  1482. X}
  1483. X
  1484. Xstatic char tday[10];
  1485. X
  1486. Xchar *
  1487. Xdates( struct DateStamp *dss, int flags )
  1488. X{
  1489. X    static char timestr[40];
  1490. X    char tdate[10], ttime[10];
  1491. X    struct DateTime dt;
  1492. X    struct DateStamp *myds=&(dt.dat_Stamp);
  1493. X
  1494. X    dt.dat_Format=FORMAT_DOS;
  1495. X    dt.dat_StrDay=tday;
  1496. X    dt.dat_StrDate=tdate;
  1497. X    dt.dat_StrTime=ttime;
  1498. X    dt.dat_Flags=flags ? DTF_SUBST : 0;
  1499. X    myds->ds_Days=dss->ds_Days;
  1500. X    myds->ds_Minute=dss->ds_Minute;
  1501. X    myds->ds_Tick=dss->ds_Tick;
  1502. X    if(StamptoStr(&dt))
  1503. X        strcpy(tdate,"<invalid>"), ttime[0]=0;
  1504. X    sprintf(timestr,"%-9s %-8s",tdate,ttime);
  1505. X    timestr[18]=0;    /* protection against bad timestamped files */
  1506. X    return timestr;
  1507. X}
  1508. X
  1509. Xint
  1510. Xdo_date( void )
  1511. X{
  1512. X    static long stopwatch;
  1513. X    struct DateStamp dss;
  1514. X    struct DateTime dt;
  1515. X    long time;
  1516. X    int i=1;
  1517. X
  1518. X    dt.dat_Format=FORMAT_DOS;
  1519. X    if (ac==1) {
  1520. X        DateStamp(&dss);
  1521. X        time=dss.ds_Minute*6000+2*dss.ds_Tick;   /* 2 = 100/TickPerSec   */
  1522. X        if( options & 1 )
  1523. X            stopwatch=time;
  1524. X        else if( options&2 )
  1525. X            printf( "%d.%02d\n",(time-stopwatch)/100,(time-stopwatch)%100);
  1526. X        else 
  1527. X            printf("%s %s\n",tday,dates(&dss,0));
  1528. X    } else {
  1529. X        DateStamp(&dt.dat_Stamp);
  1530. X        for ( ; i<ac; i++) {
  1531. X            dt.dat_StrDate=NULL;
  1532. X            dt.dat_StrTime=NULL;
  1533. X            dt.dat_Flags=DTF_FUTURE;
  1534. X            if (index(av[i],':')) dt.dat_StrTime=av[i];
  1535. X                else dt.dat_StrDate=av[i];
  1536. X            if (StrtoStamp(&dt)) ierror(av[i],500);
  1537. X        }
  1538. X        setsystemtime( & (dt.dat_Stamp) );
  1539. X    }
  1540. X    return 0;
  1541. X}
  1542. END_OF_FILE
  1543. if test 34186 -ne `wc -c <'comm1.c'`; then
  1544.     echo shar: \"'comm1.c'\" unpacked with wrong size!
  1545. fi
  1546. # end of 'comm1.c'
  1547. fi
  1548. if test -f 'comm2.c' -a "${1}" != "-c" ; then 
  1549.   echo shar: Will not clobber existing file \"'comm2.c'\"
  1550. else
  1551. echo shar: Extracting \"'comm2.c'\" \(29350 characters\)
  1552. sed "s/^X//" >'comm2.c' <<'END_OF_FILE'
  1553. X/*
  1554. X * COMM2.C
  1555. X *
  1556. X * (c)1986 Matthew Dillon     9 October 1986
  1557. X *
  1558. X * Version 2.07M by Steve Drew 10-Sep-87
  1559. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  1560. X * Version 5.00L by Urban Mueller 17-Feb-91
  1561. X *
  1562. X */
  1563. X
  1564. X#include "shell.h"
  1565. X
  1566. X/* comm2.c */
  1567. Xstatic long dptrtosecs(struct DPTR *d);
  1568. Xstatic long timeof(char *s);
  1569. Xstatic int evalif(void);
  1570. Xstatic int clinum(char *name);
  1571. Xstatic int copydir(long srcdir, long destdir, int recur);
  1572. Xstatic int copyfile(char *srcname, long srcdir, char *destname, long destdir);
  1573. Xstatic int file_date(struct DateStamp *date, char *name);
  1574. Xstatic void changedisk(struct MsgPort *task);
  1575. Xstatic int func_array( char *fav[], int fac);
  1576. Xstatic int func_int(int i);
  1577. Xstatic int func_bool(int i);
  1578. Xstatic int func_string(char *str);
  1579. Xstatic int commas(char *av[], int ac, int n);
  1580. Xstatic int wordset(char **av, int ac, char **(*func)(char **,int,char**,int,int*,int));
  1581. Xstatic int split_arg(char **av, int ac);
  1582. Xstatic char *info_part(char **av, int ac, int n, char *buf);
  1583. X
  1584. X/* Casting conveniences */
  1585. X#define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  1586. X#define PROC(task)              ((struct Process *)task)
  1587. X#define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  1588. X
  1589. X/* Externs */
  1590. Xextern int has_wild;                    /* flag set if any arg has a ? or * */
  1591. X
  1592. X/* globals */
  1593. Xstatic int cp_update, cp_date, cp_flags, cp_fresh, cp_move;
  1594. X
  1595. Xdo_abortline( void )
  1596. X{
  1597. X    Exec_abortline = 1;
  1598. X    return 0;
  1599. X}
  1600. X
  1601. Xdo_error( void )
  1602. X{
  1603. X    return atoi(av[1]);
  1604. X}
  1605. X
  1606. Xdo_return( void )
  1607. X{
  1608. X    int retcode=(ac<2 ? 0 : atoi(av[1]));
  1609. X
  1610. X    Exec_abortline = 1;
  1611. X    if (Src_stack) {
  1612. X        Src_abort[Src_stack-1]=1;
  1613. X        return retcode;
  1614. X    } else
  1615. X        main_exit(retcode);
  1616. X    return 0;
  1617. X}
  1618. X
  1619. X/*
  1620. X * STRHEAD
  1621. X *
  1622. X * place a string into a variable removing everything after and including
  1623. X * the 'break' character
  1624. X *
  1625. X * strhead varname breakchar string
  1626. X *
  1627. X */
  1628. X
  1629. Xdo_strhead( void )
  1630. X{
  1631. X    char *s;
  1632. X    if (*av[2] && (s=index( av[3], *av[2]))) 
  1633. X        *s='\0';
  1634. X    set_var (LEVEL_SET, av[1], av[3]);
  1635. X    return 0;
  1636. X}
  1637. X
  1638. Xdo_strtail( void )
  1639. X{
  1640. X    char *s;
  1641. X    if (*av[2] && (s=index(av[3],*av[2]))) s++; else s=av[3];
  1642. X    set_var (LEVEL_SET, av[1], s);
  1643. X    return 0;
  1644. X}
  1645. X
  1646. Xstatic long
  1647. Xdptrtosecs(struct DPTR *d)
  1648. X{
  1649. X    struct DateStamp *ds=(&d->fib->fib_Date);
  1650. X    return ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
  1651. X}
  1652. X
  1653. Xstatic long
  1654. Xtimeof(char *s)
  1655. X{
  1656. X    struct DPTR *d;
  1657. X    int dummy;
  1658. X    long n;
  1659. X
  1660. X    if ( (d=dopen(s,&dummy))==NULL ) return 0L;
  1661. X    n=dptrtosecs(d);
  1662. X    dclose(d);
  1663. X    return n;
  1664. X}
  1665. X
  1666. X/*
  1667. X * if -f file (exists) or:
  1668. X *
  1669. X * if A < B   <, >, =, <=, >=, <>, where A and B are either:
  1670. X * nothing
  1671. X * a string
  1672. X * a value (begins w/ number)
  1673. X */
  1674. X
  1675. Xdo_if( char *garbage, int com )
  1676. X{
  1677. X    int result;
  1678. X
  1679. X    switch (com) {
  1680. X    case 0:
  1681. X        if (If_stack && If_base[If_stack - 1])
  1682. X            If_base[If_stack++] = 1;
  1683. X        else {
  1684. X            result=evalif();
  1685. X            If_base[If_stack++]=(options & 64 ? result : !result);
  1686. X        }
  1687. X        break;
  1688. X    case 1:
  1689. X        if (If_stack > 1 && If_base[If_stack - 2]) break;
  1690. X        if (If_stack) If_base[If_stack - 1] ^= 1;
  1691. X        break;
  1692. X    case 2:
  1693. X        if (If_stack) --If_stack;
  1694. X        break;
  1695. X    }
  1696. X    disable = (If_stack) ? If_base[If_stack - 1] : 0;
  1697. X    if (If_stack >= MAXIF) {
  1698. X        fprintf(stderr,"If's too deep\n");
  1699. X        disable = If_stack = 0;
  1700. X        return -1;
  1701. X    }
  1702. X    if (forward_goto) disable = If_base[If_stack - 1] = 0;
  1703. X    return 0;
  1704. X}
  1705. X
  1706. Xstatic int
  1707. Xevalif()
  1708. X{
  1709. X    char c, *str, *left, *right, *cmp;
  1710. X    long num, t0, isint, i=1;
  1711. X
  1712. X    switch(options & ~64) {
  1713. X    case 0:
  1714. X        for( i=1; i<ac; i++ )
  1715. X            if( strlen(str=av[i])<=2 && *str && index("<=>",*str) &&
  1716. X                   (!str[1] || index("<=>",str[1])))
  1717. X                break;
  1718. X
  1719. X        if ( i==ac )
  1720. X            return ac>1 && *av[1] && strcmp(av[1],"0");
  1721. X
  1722. X        left =av[1];
  1723. X        right=av[i+1];
  1724. X        if( 1+1!=i )    left = compile_av(av,1,i   ,0xA0, 0);
  1725. X        if( i+1+1!=ac ) right= compile_av(av,i+1,ac,0xA0, 0);
  1726. X        cmp  = av[i];
  1727. X        num  = Atol(left);
  1728. X        isint  = ! IoErr();
  1729. X        num -= Atol(right);
  1730. X        isint &= ! IoErr();
  1731. X        if (!isint) num=strcmp(left,right);
  1732. X        if( 1+1!=i )    free(left); 
  1733. X        if( i+1+1!=ac ) free(right);
  1734. X
  1735. X        if (num < 0)       c='<';
  1736. X        else if (num > 0)  c='>';
  1737. X        else               c='=';
  1738. X        return index(cmp, c) != NULL;
  1739. X    case 1:
  1740. X        return do_rpn(NULL,i);
  1741. X    case 2:
  1742. X        return exists(av[i]);
  1743. X    case 4:
  1744. X        t0=timeof(av[i++]);
  1745. X        for ( ; i<ac ; i++)
  1746. X            if (t0<=timeof(av[i])) return 1;
  1747. X        return 0;
  1748. X    case 8:
  1749. X        return AvailMem( MEMF_FAST )!=0;
  1750. X    case 16:
  1751. X        return isdir(av[i])!=0;
  1752. X    case 32:
  1753. X        return get_var(LEVEL_SET,av[i]) != 0;
  1754. X    default:
  1755. X        ierror(NULL,500);
  1756. X    }
  1757. X    return 0;
  1758. X}
  1759. X
  1760. X#if 0
  1761. Xdo_while( void )
  1762. X{
  1763. X    char *com=av[--ac];
  1764. X    int ret=0;
  1765. X
  1766. X    while( evalif() && ret==0 && !CHECKBREAK() )
  1767. X        ret=execute( com );
  1768. X    return ret;
  1769. X}
  1770. X#endif
  1771. X
  1772. X
  1773. Xdo_label( void )
  1774. X{
  1775. X    char aseek[32];
  1776. X
  1777. X    if (Src_stack == 0) {
  1778. X        ierror (NULL, 502);
  1779. X        return -1;
  1780. X    }
  1781. X
  1782. X    sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
  1783. X    set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
  1784. X    if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
  1785. X        forward_goto = 0;
  1786. X    return 0;
  1787. X}
  1788. X
  1789. Xdo_goto( void )
  1790. X{
  1791. X    int new;
  1792. X    long pos;
  1793. X    char *lab;
  1794. X
  1795. X    if (Src_stack == 0) {
  1796. X        ierror (NULL, 502);
  1797. X    } else {
  1798. X        lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
  1799. X        if (lab == NULL) {
  1800. X            forward_goto = 1;
  1801. X            set_var (LEVEL_SET, v_gotofwd, av[1]);
  1802. X            return(0);
  1803. X        } else {
  1804. X            pos = atoi(lab);
  1805. X            fseek (Src_base[Src_stack - 1], pos, 0);
  1806. X            Src_pos[Src_stack - 1] = pos;
  1807. X            new = atoi(next_word(lab));
  1808. X            for (; If_stack < new; ++If_stack)
  1809. X                If_base[If_stack] = 0;
  1810. X            If_stack = new;
  1811. X        }
  1812. X    }
  1813. X    Exec_abortline = 1;
  1814. X    return (0);      /* Don't execute rest of this line */
  1815. X}
  1816. X
  1817. X
  1818. Xdo_inc(char *garbage, int com)
  1819. X{
  1820. X    char *var, num[32];
  1821. X
  1822. X    if (ac>2) com *= atoi(av[2]);
  1823. X    if (var = get_var (LEVEL_SET, av[1])) {
  1824. X        sprintf (num, "%d", atoi(var)+com);
  1825. X        set_var (LEVEL_SET, av[1], num);
  1826. X    }
  1827. X    return 0;
  1828. X}
  1829. X
  1830. XBPTR Input(void);
  1831. XBPTR Output(void);
  1832. Xlong IsInteractive(BPTR file);
  1833. X
  1834. Xdo_input( void )
  1835. X{
  1836. X    char *str, in[256], *get, *put;
  1837. X    int i, quote=0;
  1838. X
  1839. X    if( options&2 ) {
  1840. X        if( !IsInteractive(Input()) ) return 20;
  1841. X        setrawcon( -1, 0 );
  1842. X        in[1]=0;
  1843. X        for ( i=1; i<ac; ++i) {
  1844. X            in[0]=getchar();
  1845. X            set_var (LEVEL_SET, av[i], in);
  1846. X        }
  1847. X        setrawcon( 2, 0 );
  1848. X        return 0;
  1849. X    }
  1850. X
  1851. X    for ( i=1; i<ac; ++i)
  1852. X        if (fgets(in,256,stdin)) {
  1853. X            str=in, put=in+strlen(in)-1;
  1854. X            if( *put=='\n' ) *put=0;
  1855. X            if( !(options&1) ) {
  1856. X                while( *str==' ' ) str++;
  1857. X                for( put=get=str; *get; ) {
  1858. X                    if( *get=='\"' )
  1859. X                        quote=1-quote, get++;
  1860. X                    else if( *get==' ' && !quote ) {
  1861. X                        while( *get==' ' ) get++;
  1862. X                        if( *get ) *put++=0xA0;
  1863. X                    } else 
  1864. X                        *put++=*get++;
  1865. X                }
  1866. X                *put=0;
  1867. X                while( put>str && *(put-1)==0xA0 ) *--put=0;
  1868. X            }
  1869. X            set_var (LEVEL_SET, av[i], str);
  1870. X        }
  1871. X    return 0;
  1872. X}
  1873. X
  1874. Xdo_ver( void )
  1875. X{
  1876. X    extern char shellname[];
  1877. X
  1878. X    puts(shellname);
  1879. X    puts("1.00 Lattice (c) 1986 Matthew Dillon\n"
  1880. X         "2.05 Manx (M) versions by Steve Drew\n"
  1881. X         "3.02 ARP (A) versions by Carlo Borreo, Cesare Dieni\n"
  1882. X         "4.00 ARP 1.3 version by Carlo Borreo, Cesare Dieni\n"
  1883. X         "5.00 Lattice version by Urban Mueller (umueller@iiic.ethz.ch)\n");
  1884. X    printf("Compiled: "__DATE__" "__TIME__" with "COMPILER"\n" );
  1885. X    return 0;
  1886. X}
  1887. X
  1888. X
  1889. Xstatic int
  1890. Xclinum( char *name )
  1891. X{
  1892. X    int ncli=(long)FindCLI(0L), count;
  1893. X    struct Task *task;
  1894. X    char cmd[40+1];
  1895. X
  1896. X    if( *name>='0' && *name<='9' )
  1897. X        return atoi( name );
  1898. X
  1899. X    Forbid();
  1900. X    for (count = 1; count <= ncli ; count++)
  1901. X        if (task = (struct Task *)FindCLI(count)) {
  1902. X            if ( !PROC(task)->pr_TaskNum || PROC(task)->pr_CLI == 0) continue;
  1903. X            BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  1904. X            if( !Strcmp( BaseName( cmd ), name ))
  1905. X                goto done;
  1906. X        }
  1907. X    count=-1;
  1908. Xdone:
  1909. X    Permit();
  1910. X    return count;
  1911. X}
  1912. X
  1913. Xdo_ps( void )
  1914. X{
  1915. X    /* this code fragment based on ps.c command by Dewi Williams */
  1916. X    int count;             /* loop variable         */
  1917. X    struct Task *task;     /* EXEC descriptor       */
  1918. X    char strbuf[64+1];     /* scratch for btocstr() */
  1919. X    char cmd[40+1], *com;  /* holds cmd name        */
  1920. X    long ncli,mycli,cli,i;
  1921. X
  1922. X    char onoff[80];
  1923. X    memset( onoff, 0, 80 );
  1924. X    for( i=1; i<ac; i++ )
  1925. X        onoff[ 1+clinum( av[i] ) ]=1;
  1926. X    if( options&2 )
  1927. X        for( i=0; i<80; i++ )
  1928. X            onoff[i]=1-onoff[i];
  1929. X
  1930. X    printf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
  1931. X    Forbid();
  1932. X
  1933. X    ncli=(long)FindCLI(0L);
  1934. X    mycli=interactive() ? Myprocess->pr_TaskNum : -1;
  1935. X    for (count = 1; count <= ncli ; count++)             /* or just assume 20?*/
  1936. X        if (task = (struct Task *)FindCLI((long)count)) {/* Sanity check      */
  1937. X            cli=PROC(task)->pr_TaskNum;
  1938. X            if( ac>1 && !onoff[1+cli] )
  1939. X                continue;
  1940. X            if ( cli==0 || PROC(task)->pr_CLI == 0) continue; /* or complain? */
  1941. X                BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
  1942. X                BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
  1943. X            com=cmd;
  1944. X            if( !(options&1) )
  1945. X                com=BaseName(com);
  1946. X            printf("%c%2d  %-20.20s %-11.11s %3d  %8lx  %s\n",
  1947. X                cli==mycli ? '*' : ' ',
  1948. X                count,
  1949. X                com,
  1950. X                task->tc_Node.ln_Name,
  1951. X                (signed char)task->tc_Node.ln_Pri,
  1952. X                task,
  1953. X                strbuf
  1954. X            );
  1955. X        }
  1956. X
  1957. X    Permit();
  1958. X    return 0;
  1959. X}
  1960. X
  1961. X/*
  1962. X * CP [-d] [-u] file file
  1963. X * CP [-d] [-u] file file file... destdir
  1964. X * CP [-r][-u][-d] dir dir dir... destdir
  1965. X */
  1966. X
  1967. Xchar *errstr;          /* let's be alittle more informative */
  1968. X
  1969. Xdo_copy( void )
  1970. X{
  1971. X    int recur, ierr;
  1972. X    char *destname;
  1973. X    char destisdir;
  1974. X    FIB *fib;
  1975. X    int i=1;
  1976. X
  1977. X    errstr = "";
  1978. X    ierr = 0;
  1979. X
  1980. X    fib = (FIB *)SAllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  1981. X
  1982. X    recur     = (options & 0x01);
  1983. X    cp_update = (options & 0x02);
  1984. X    cp_date   =!(options & 0x04); /* the default is keep orignal file date */
  1985. X    cp_flags  =!(options & 0x08);
  1986. X    cp_fresh  = (options & 0x10);
  1987. X    cp_move   = (options & 0x20);
  1988. X
  1989. X    destname = av[ac - 1];
  1990. X
  1991. X    if (ac < i + 2) {
  1992. X        ierr = 500;
  1993. X        goto done;
  1994. X    }
  1995. X    destisdir = isdir(destname);
  1996. X    if (ac > i + 2 && !destisdir) {
  1997. X        ierr = 507;
  1998. X        goto done;
  1999. X    }
  2000. X
  2001. X/*
  2002. X * copy set:                        reduce to:
  2003. X *    file to file                     file to file
  2004. X *    dir  to file (NOT ALLOWED)
  2005. X *    file to dir                      dir to dir
  2006. X *    dir  to dir                      dir to dir
  2007. X *
  2008. X */
  2009. X
  2010. X    for (; i<ac-1 && !dobreak(); ++i) {
  2011. X        short srcisdir = isdir(av[i]);
  2012. X        if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
  2013. X            continue;                    /* getting copied if specified */
  2014. X                                         /* from wild expansion         */
  2015. X        if (srcisdir) {
  2016. X            BPTR srcdir, destdir;
  2017. X            if (!destisdir) {
  2018. X                if (exists(destname)) {
  2019. X                    ierr = 507;    /* disallow dir to file */
  2020. X                    goto done;
  2021. X                    }
  2022. X                if (destdir = CreateDir(destname)) UnLock(destdir);
  2023. X                destisdir = 1;
  2024. X            }
  2025. X            if (!(destdir = Lock(destname, ACCESS_READ))) {
  2026. X                ierr = 205;
  2027. X                errstr = destname;
  2028. X                goto done;
  2029. X            }
  2030. X            if (!(srcdir = Lock(av[i], ACCESS_READ))) {
  2031. X                ierr = 205;
  2032. X                errstr = av[i];
  2033. X                UnLock(destdir);
  2034. X                goto done;
  2035. X            }
  2036. X            ierr = copydir(srcdir, destdir, recur);
  2037. X            UnLock(srcdir);
  2038. X            UnLock(destdir);
  2039. X            if (ierr) break;
  2040. X        } else {                   /* FILE to DIR,   FILE to FILE   */
  2041. X            BPTR destdir, srcdir, tmp;
  2042. X            char *destfilename;
  2043. X
  2044. X            srcdir = (BPTR)(Myprocess->pr_CurrentDir);
  2045. X
  2046. X            if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
  2047. X                if (tmp) UnLock(tmp);
  2048. X                ierr = 205;
  2049. X                errstr = av[i];
  2050. X                goto done;
  2051. X            }
  2052. X            UnLock(tmp);
  2053. X            if (destisdir) {
  2054. X                destdir = Lock(destname, ACCESS_READ);
  2055. X                destfilename = fib->fib_FileName;
  2056. X            } else {
  2057. X                destdir = srcdir;
  2058. X                destfilename = destname;
  2059. X            }
  2060. X            printf(" %s..",av[i]);
  2061. X            fflush(stdout);
  2062. X            ierr = copyfile(av[i], srcdir, destfilename, destdir);
  2063. X            if (destisdir) UnLock(destdir);
  2064. X            if (ierr) break;
  2065. X        }
  2066. X    }
  2067. X
  2068. Xdone:
  2069. X
  2070. X    FreeMem(fib, (long)sizeof(FIB));
  2071. X    if (ierr) {
  2072. X        ierror(errstr, ierr);
  2073. X        return(20);
  2074. X    }
  2075. X    return 0;
  2076. X}
  2077. X
  2078. Xstatic int
  2079. Xcopydir(BPTR srcdir, BPTR destdir, int recur)
  2080. X{
  2081. X    static int level;
  2082. X    BPTR cwd;
  2083. X    FIB *srcfib;
  2084. X    BPTR destlock, srclock;
  2085. X    int ierr=0;
  2086. X
  2087. X    level++;
  2088. X
  2089. X    srcfib = (FIB *)SAllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  2090. X    if( !Examine(srcdir, srcfib)) {
  2091. X        ierr=IoErr();
  2092. X        goto exit;
  2093. X    }
  2094. X
  2095. X    while (ExNext(srcdir, srcfib)) {
  2096. X        if (CHECKBREAK())
  2097. X            break;
  2098. X        if (srcfib->fib_DirEntryType < 0) {
  2099. X            printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
  2100. X            fflush(stdout);
  2101. X            ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
  2102. X            if (ierr) break;
  2103. X        } else {
  2104. X            if ( srcfib->fib_DirEntryType!=ST_USERDIR ) {
  2105. X                printf("%*s%s (Dir)....[Skipped. Is a link]\n",(level-1) * 6,
  2106. X                               " ",srcfib->fib_FileName);
  2107. X                continue;
  2108. X            }
  2109. X            if (recur) {
  2110. X                cwd = CurrentDir(srcdir);
  2111. X                if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
  2112. X                    CurrentDir(destdir);
  2113. X                    if (!(destlock = Lock(srcfib->fib_FileName,ACCESS_WRITE))) {
  2114. X                        destlock = CreateDir(srcfib->fib_FileName);
  2115. X                        printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
  2116. X                               " ",srcfib->fib_FileName);
  2117. X
  2118. X                        /* UnLock and re Lock if newly created
  2119. X                         * for file_date() to work properly */
  2120. X                        if (destlock)
  2121. X                            UnLock(destlock);
  2122. X                        destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE);
  2123. X                    } else
  2124. X                        printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
  2125. X                    if (destlock) {
  2126. X                        ierr = copydir(srclock, destlock, recur);
  2127. X                        UnLock(destlock);
  2128. X                    } else {
  2129. X                        ierr = (int)((long)IoErr());
  2130. X                    }
  2131. X                    UnLock(srclock);
  2132. X                } else {
  2133. X                    ierr = (int)((long)IoErr());
  2134. X                }
  2135. X                CurrentDir(cwd);
  2136. X                if (ierr)
  2137. X                    break;
  2138. X            }
  2139. X        }
  2140. X    }
  2141. Xexit:
  2142. X    --level;
  2143. X    FreeMem(srcfib, (long)sizeof(FIB));
  2144. X    return(ierr);
  2145. X}
  2146. X
  2147. X#define COPYBUF 32768
  2148. X
  2149. Xstatic int
  2150. Xcopyfile(char *srcname, BPTR srcdir, char *destname, BPTR destdir)
  2151. X{
  2152. X    BPTR cwd;
  2153. X    BPTR f1, f2;
  2154. X    long i;
  2155. X    int stat,ierr;
  2156. X    char *buf;
  2157. X    struct DPTR *dp, *dps;
  2158. X
  2159. X    if ((buf = (char *)AllocMem(COPYBUF, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  2160. X        { ierr = 103; goto fail2; }
  2161. X    ierr = 0;
  2162. X    cwd = CurrentDir(srcdir);
  2163. X    if ((f1=Open(srcname, MODE_OLDFILE))==NULL)
  2164. X        { errstr = srcname; ierr = 205; goto fail; }
  2165. X    dps = dopen(srcname,&stat);
  2166. X    CurrentDir(destdir);
  2167. X    if (cp_update || cp_fresh) {
  2168. X        if( dp=dopen(destname, &stat) ) {
  2169. X            if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
  2170. X                      !Strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
  2171. X            { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
  2172. X            dclose(dp);
  2173. X        } else if( cp_fresh ) {
  2174. X            Close(f1); printf("..not there\n"); goto fail;
  2175. X        }
  2176. X    }
  2177. X    if ((f2=Open(destname, MODE_NEWFILE))==NULL)
  2178. X        { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
  2179. X    while (i = Read(f1, buf, COPYBUF))
  2180. X        if( dobreak() )
  2181. X            { ierr=513; break; }
  2182. X        else if (Write(f2, buf, i) != i)
  2183. X            { ierr = IoErr(); break; }
  2184. X    Close(f2);
  2185. X    Close(f1);
  2186. X    if (!ierr) {
  2187. X        if (cp_date) file_date(&dps->fib->fib_Date, destname);
  2188. X        if (cp_flags ) {
  2189. X            SetProtection( destname, dps->fib->fib_Protection&~FIBF_ARCHIVE);
  2190. X            if( *dps->fib->fib_Comment )
  2191. X                SetComment( destname, dps->fib->fib_Comment );
  2192. X        }
  2193. X        dclose(dps); dps=NULL;
  2194. X        if( cp_move ) {
  2195. X            CurrentDir(srcdir);
  2196. X            DeleteFile(srcname);
  2197. X            printf("..moved\n");
  2198. X        } else
  2199. X            printf("..copied\n");
  2200. X    } else {
  2201. X        DeleteFile(destname);
  2202. X    }
  2203. Xfail:
  2204. X    if( dps ) dclose(dps);
  2205. X    if (buf) FreeMem(buf, COPYBUF);
  2206. X    CurrentDir(cwd);
  2207. Xfail2:
  2208. X    return(ierr);
  2209. X}
  2210. X
  2211. Xdo_touch( void )
  2212. X{
  2213. X    struct DateStamp ds;
  2214. X    int i;
  2215. X    DateStamp(&ds);
  2216. X    for (i=1; i<ac; i++)
  2217. X        if (file_date(&ds, av[i]))
  2218. X            ierror(av[i],500);
  2219. X        else 
  2220. X            clear_archive_bit( av[i] );
  2221. X    return 0;
  2222. X}
  2223. X
  2224. X
  2225. Xstatic int
  2226. Xfile_date( struct DateStamp *date, char *name )
  2227. X{
  2228. X    long packargs[7];
  2229. X    struct MsgPort *task;
  2230. X    struct DPTR *tmp;
  2231. X    BPTR dirlock;
  2232. X    char *ptr;
  2233. X    int stat;
  2234. X
  2235. X    if (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
  2236. X    if (tmp = dopen(name, &stat)) {
  2237. X        dirlock = ParentDir(tmp->lock);
  2238. X        ptr=SAllocMem(65L,MEMF_PUBLIC);
  2239. X        CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
  2240. X        dclose(tmp);
  2241. X        packargs[1]=dirlock;
  2242. X        packargs[2]=(ULONG)ptr >> 2L;
  2243. X        packargs[3]=(long)date;
  2244. X        SendPacket(ACTION_SET_DATE,packargs,task);
  2245. X        UnLock(dirlock);
  2246. X        FreeMem(ptr,65L);
  2247. X    }
  2248. X    return 0;
  2249. X}
  2250. X
  2251. Xdo_addbuffers( void )
  2252. X{
  2253. X    long packargs[7], i;
  2254. X    struct MsgPort *task;
  2255. X
  2256. X    for( i=1; i<=ac-2; i+=2 ) {
  2257. X        if( i==ac-1 )
  2258. X            { ierror( av[i], 500 ); return 20; }
  2259. X        if( !(task=(struct MsgPort *)DeviceProc(av[i])))
  2260. X            { ierror(av[1],510); return 20; }
  2261. X        packargs[0]=myatoi(av[i+1],1,32767); if (atoierr) return 20;
  2262. X        SendPacket(ACTION_MORE_CACHE,packargs,task);
  2263. X    }
  2264. X    return 0;
  2265. X}
  2266. X
  2267. Xdo_relabel( void )
  2268. X{
  2269. X    long packargs[7];
  2270. X    struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  2271. X    char *ptr;
  2272. X
  2273. X    if (!task) { ierror(av[1],510); return 20; }
  2274. X    ptr=SAllocMem(65L,MEMF_PUBLIC);
  2275. X    CtoBStr(av[2],(ULONG)ptr >> 2L,64L);
  2276. X    packargs[0]=(ULONG)ptr >> 2L;
  2277. X    SendPacket(ACTION_RENAME_DISK,packargs,task);
  2278. X    FreeMem(ptr,65L);
  2279. X    Delay(10);
  2280. X    changedisk(task);
  2281. X    return 0;
  2282. X}
  2283. X
  2284. Xdo_diskchange( void )
  2285. X{
  2286. X    struct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
  2287. X
  2288. X    if (!task) { ierror(av[1],510); return 20; }
  2289. X    changedisk(task);
  2290. X    return 0;
  2291. X}
  2292. X
  2293. Xstatic void
  2294. Xchangedisk(struct MsgPort *task)
  2295. X{
  2296. X    long packargs[7];
  2297. X
  2298. X    packargs[0]=1L;
  2299. X    SendPacket(ACTION_INHIBIT,packargs,task);
  2300. X    packargs[0]=0L;
  2301. X    SendPacket(ACTION_INHIBIT,packargs,task);
  2302. X}
  2303. X
  2304. X
  2305. Xextern int atoierr;
  2306. X
  2307. Xstatic int
  2308. Xfunc_array( char *fav[], int fac)
  2309. X{
  2310. X    char *ret;
  2311. X    if( atoierr ) return 20;
  2312. X    if( fac ) {
  2313. X        ret=compile_av( fav, 0, fac, 0xa0, 0);
  2314. X        set_var( LEVEL_SET, v_value, ret );
  2315. X        free( ret );
  2316. X    } else 
  2317. X        unset_var( LEVEL_SET, v_value );
  2318. X    return 0;
  2319. X}
  2320. X
  2321. Xstatic int
  2322. Xfunc_int( int i )
  2323. X{
  2324. X    char buf[12];
  2325. X    if( atoierr ) return 20;
  2326. X    sprintf(buf,"%d",i);
  2327. X    set_var( LEVEL_SET, v_value, buf );
  2328. X    return 0;
  2329. X}
  2330. X
  2331. Xstatic int
  2332. Xfunc_bool( int i )
  2333. X{
  2334. X    if( atoierr ) return 20;
  2335. X    set_var( LEVEL_SET, v_value, i ? "1" : "0" );
  2336. X    return 0;
  2337. X}
  2338. X
  2339. Xstatic int
  2340. Xfunc_string( char *str )
  2341. X{
  2342. X    if( atoierr ) return 20;
  2343. X    set_var( LEVEL_SET, v_value, str ? str : "" );
  2344. X    return 0;
  2345. X}
  2346. X
  2347. Xstatic int
  2348. Xcommas( char *av[], int ac, int n )
  2349. X{
  2350. X    int i=0;
  2351. X
  2352. X    while( --ac>=0 )
  2353. X        if( !strcmp( *av++, ",") )
  2354. X            i++;
  2355. X    if( i-=n )
  2356. X        fprintf( stderr, "Need %d comma%s\n", n, (n==1) ? "" : "s" );
  2357. X    return i;
  2358. X}
  2359. X
  2360. Xstatic int
  2361. Xwordset( char *av[], int ac, char **(*func)(char **,int,char**,int,int*,int) )
  2362. X{
  2363. X    char **av1=av, **av2;
  2364. X    int  ac1=0, ac2, ret;
  2365. X
  2366. X    if( commas( av, ac, 1 ) ) return 20;
  2367. X    while( strcmp( *av++, ",") ) ac1++;
  2368. X    av2=av, ac2=ac-ac1-1;
  2369. X    av=(*func)( av1, ac1, av2, ac2, &ac, 0 );
  2370. X    ret=func_array( av, ac );
  2371. X    free( av );
  2372. X    return ret;
  2373. X}
  2374. X
  2375. Xstatic int
  2376. Xsplit_arg( char **av, int ac )
  2377. X{
  2378. X    char **arr, **old, *arg;
  2379. X    int i, j=1, ret;
  2380. X
  2381. X    for( i=strlen(av[0])-1; i>=0; i-- )
  2382. X        if( av[0][i]==' ' )
  2383. X            av[0][i]=0, j++;
  2384. X
  2385. X    arr=old=(char **)salloc( j*sizeof( char * ) );
  2386. X    arg=*av;
  2387. X    for( ; j>0; j-- ) {
  2388. X        *arr++=arg;
  2389. X        arg+=strlen(arg)+1;
  2390. X    }
  2391. X    ret=func_array( old, arr-old );
  2392. X    free(old);
  2393. X    return ret;
  2394. X}
  2395. X
  2396. Xstatic char *
  2397. Xinfo_part( char **av, int ac, int n, char *buf )
  2398. X{
  2399. X    char *str;
  2400. X    struct DPTR *dp;
  2401. X    int len=0, i, t;
  2402. X
  2403. X    buf[0]=0;
  2404. X    while( --ac>=0 ) {
  2405. X        if( dp=dopen( av[0], &t) ) {
  2406. X            if( n==0 ) {
  2407. X                for (str=buf, i=7; i>=0; i--)
  2408. X                    *str++= (dp->fib->fib_Protection & (1L<<i) ?
  2409. X                            "hspa----" : "----rwed")[7-i];
  2410. X                *str=0;
  2411. X            } else len+= dp->fib->fib_NumBlocks+1;
  2412. X            dclose( dp );
  2413. X        }
  2414. X    }
  2415. X    if( n ) sprintf(buf, "%d", len);
  2416. X    return buf;
  2417. X}
  2418. X
  2419. Xstatic struct FileRequester freq;
  2420. X
  2421. Xstatic char *
  2422. Xfile_request(char **av, int ac, char *path)
  2423. X{
  2424. X    struct FileRequester fr;
  2425. X    char filebuf[128];
  2426. X
  2427. X    path[0]=0; filebuf[0]=0;
  2428. X    fr=freq; /* clear everything */
  2429. X    fr.fr_Hail="";
  2430. X    if( ac>0 ) {
  2431. X        fr.fr_Hail=av[0];
  2432. X        if( ac>1 ) {
  2433. X            strcpy( path,av[1]);
  2434. X            if( ac>2 )
  2435. X                strcpy(filebuf,av[2]);
  2436. X        }
  2437. X    }
  2438. X    fr.fr_File  = filebuf;
  2439. X    fr.fr_Dir   = path;
  2440. X    fr.fr_Flags2= FR2F_LongPath;
  2441. X    if( !FileRequest( &fr ) )
  2442. X        return NULL;
  2443. X    TackOn( path,filebuf );
  2444. X    return path;
  2445. X}
  2446. X
  2447. Xint
  2448. Xconfirm( char *title, char *file )
  2449. X{
  2450. X    char buf[80];
  2451. X
  2452. X    buf[0]=0;
  2453. X
  2454. X    if( !confirmed ) {
  2455. X        fprintf(stderr,"%s %s%-16s%s [YES/no/all/done] ? ",
  2456. X                        title,o_hilite,file,o_lolite);
  2457. X        strupr(fgets(buf,80,stdin));
  2458. X        if( *buf=='A' )
  2459. X            confirmed=1;
  2460. X        if( *buf=='D' || breakcheck() )
  2461. X            confirmed=2;
  2462. X    }
  2463. X
  2464. X    if( confirmed==2 )
  2465. X        return 0;
  2466. X    return confirmed || *buf != 'N';
  2467. X}
  2468. X
  2469. Xenum funcid {
  2470. X    FN_STUB=1, FN_MEMBER, FN_DIRS, FN_NAMEEXT, FN_NAMEROOT, FN_FILES,
  2471. X    FN_FILELEN, FN_SORTARGS, FN_UPPER, FN_WORDS, FN_ABBREV, FN_ABS,
  2472. X    FN_BINTODEC, FN_CENTER, FN_COMPARE, FN_DECTOHEX, FN_DELWORD,
  2473. X    FN_DELWORDS, FN_EXISTS, FN_INDEX, FN_STRCMP, FN_SUBWORDS,
  2474. X    FN_WORD, FN_MIN, FN_MAX, FN_DRIVES, FN_WITHOUT, FN_UNION, FN_INTERSECT,
  2475. X    FN_AVAILMEM, FN_UNIQUE, FN_RPN, FN_CONCAT, FN_SPLIT, FN_DRIVE,
  2476. X    FN_FILEPROT, FN_FILEBLKS, FN_LOWER, FN_HOWMANY, FN_COMPLETE, FN_FIRST,
  2477. X    FN_LAST, FN_MATCH, FN_CLINUM, FN_FREEBYTES, FN_FREEBLKS, FN_INFO,
  2478. X    FN_MEGS, FN_FREESTORE, FN_CHECKPORT, FN_PICKOPTS, FN_PICKARGS,
  2479. X    FN_FILEREQ, FN_VOLUME, FN_LOOKFOR, FN_APPSUFF, FN_PATHNAME, FN_AGE,
  2480. X    FN_GETCLASS, FN_CONFIRM, FN_WINWIDTH, FN_WINHEIGHT, FN_WINTOP,
  2481. X    FN_WINLEFT, FN_CONSOLE, FN_SORTNUM, FN_IOERROR, FN_MOUNTED
  2482. X};
  2483. X
  2484. X#define MAXAV        30000        /* Max. # of arguments            */
  2485. X
  2486. Xstruct FUNCTION {
  2487. X    short id, minargs, maxargs;
  2488. X    char *name;
  2489. X} Function[]={
  2490. XFN_ABBREV,   2, 3,     "abbrev",
  2491. XFN_ABS,      1, 1,     "abs",
  2492. XFN_AGE,      1, 1,     "age",
  2493. XFN_APPSUFF,  2, 2,     "appsuff",
  2494. XFN_AVAILMEM, 0, 1,     "availmem",
  2495. XFN_STUB,     1, 1,     "basename",
  2496. XFN_CENTER,   2, 2,     "center",
  2497. XFN_CHECKPORT,1, 1,     "checkport",
  2498. XFN_CLINUM,   1, 1,     "clinum",
  2499. XFN_COMPLETE, 1, MAXAV, "complete",
  2500. XFN_CONCAT,   0, MAXAV, "concat",
  2501. XFN_CONFIRM,  1, MAXAV, "confirm",
  2502. XFN_CONSOLE,  1, 1,     "console",
  2503. XFN_DECTOHEX, 1, 1,     "dectohex",
  2504. XFN_DELWORD,  1, MAXAV, "delword",
  2505. XFN_DELWORDS, 2, MAXAV, "delwords",
  2506. XFN_DIRS,     0, MAXAV, "dirs",
  2507. XFN_DRIVE,    1, 1,     "drive",
  2508. XFN_DRIVES,   0, 0,     "drives",
  2509. XFN_EXISTS,   1, 1,     "exists",
  2510. XFN_FILEBLKS, 1, MAXAV, "fileblks",
  2511. XFN_FILELEN,  0, MAXAV, "filelen",
  2512. XFN_FILEPROT, 1, 1,     "fileprot",
  2513. XFN_FILEREQ,  0, 3,     "filereq",
  2514. XFN_FILES,    0, MAXAV, "files",
  2515. XFN_FREEBLKS, 1, 1,     "freeblks",
  2516. XFN_FREEBYTES,1, 1,     "freebytes",
  2517. XFN_FREESTORE,1, 1,     "freestore",
  2518. XFN_FIRST,    0, MAXAV, "first",
  2519. XFN_STUB,     1, 1,     "getenv",
  2520. XFN_GETCLASS, 1, 1,     "getclass",
  2521. XFN_HOWMANY,  0, 0,     "howmany",
  2522. XFN_IOERROR,  1, 1,     "ioerr",
  2523. XFN_INDEX,    2, 2,     "index",
  2524. XFN_INFO,     1, 1,     "info",
  2525. XFN_INTERSECT,1, MAXAV, "intersect",
  2526. XFN_LAST,     0, MAXAV, "last",
  2527. XFN_LOOKFOR,  2, 2,     "lookfor",
  2528. XFN_LOWER,    0, MAXAV, "lower",
  2529. XFN_MATCH,    1, MAXAV, "match",
  2530. XFN_MAX,      1, MAXAV, "max",
  2531. XFN_MEGS,     1, 1,     "megs",
  2532. XFN_MEMBER,   1, MAXAV, "member",
  2533. XFN_MIN,      1, MAXAV, "min",
  2534. XFN_MOUNTED,  1, 1,     "mounted",
  2535. XFN_NAMEEXT,  1, 1,     "nameext",
  2536. XFN_NAMEROOT, 1, 1,     "nameroot",
  2537. XFN_PATHNAME, 1, 1,     "pathname",
  2538. XFN_PICKARGS, 0, MAXAV, "pickargs",
  2539. XFN_PICKOPTS, 0, MAXAV, "pickopts",
  2540. XFN_RPN,      1, MAXAV, "rpn",
  2541. XFN_SORTARGS, 0, MAXAV, "sortargs",
  2542. XFN_SORTNUM,  0, MAXAV, "sortnum",
  2543. XFN_SPLIT,    0, MAXAV, "split",
  2544. XFN_STRCMP,   2, 2,     "strcmp",
  2545. XFN_STUB,     2, 2,     "strhead",
  2546. XFN_STUB,     2, 2,     "strleft",
  2547. XFN_STUB,     2, 3,     "strmid",
  2548. XFN_STUB,     2, 2,     "strright",
  2549. XFN_STUB,     2, 2,     "strtail",
  2550. XFN_SUBWORDS, 2, MAXAV, "subwords",
  2551. XFN_STUB,     2, 2,     "tackon",
  2552. XFN_UNION,    1, MAXAV, "union",
  2553. XFN_UNIQUE,   0, MAXAV, "unique",
  2554. XFN_UPPER,    0, MAXAV, "upper",
  2555. XFN_VOLUME,   1, 1,     "volume",
  2556. XFN_WINHEIGHT,0, 0,     "winheight",
  2557. XFN_WINLEFT,  0, 0,     "winleft",
  2558. XFN_WINTOP,   0, 0,     "wintop",
  2559. XFN_WINWIDTH, 0, 0,     "winwidth",
  2560. XFN_WITHOUT,  1, MAXAV, "without",
  2561. XFN_WORD,     1, MAXAV, "word",
  2562. XFN_WORDS,    0, MAXAV, "words",
  2563. X0,           0, NULL
  2564. X};
  2565. X
  2566. Xextern char shellctr[];
  2567. X
  2568. Xint
  2569. Xdofunc( int id, char **av, int ac)
  2570. X{
  2571. X    char **oldav=av, **get=av, buf[200], *str=buf;
  2572. X    int oldac=ac, i=0, j=0, n=0, n2=1, l;
  2573. X    buf[0]=0;
  2574. X    av[ac]=NULL;
  2575. X
  2576. X    switch( id ) {
  2577. X    case FN_ABBREV:
  2578. X        if( ac==3 ) i=posatoi(av[2] ); else i=strlen(av[0]);
  2579. X        return func_bool( !Strncmp( av[0], av[1], i ));
  2580. X    case FN_ABS:
  2581. X        i=unlatoi(av[0]);
  2582. X        return func_int( i>= 0 ? i : -i );
  2583. X    case FN_AGE: {
  2584. X        struct DateStamp ds; long time;
  2585. X        DateStamp( &ds ); if( ds.ds_Days==0 ) return 99999;
  2586. X        if( !(time=timeof(av[0]))) return 99999;
  2587. X        return func_int( (ds.ds_Days*86400+ds.ds_Minute*60-time)/86400 ); }
  2588. X    case FN_APPSUFF:
  2589. X        strcpy(buf,av[0]);
  2590. X        l=strlen(av[0])-strlen(av[1]);
  2591. X        if( l<0 || Strcmp(av[0]+l,av[1])) {
  2592. X            strcat(buf,".");
  2593. X            strcat(buf,av[1]);
  2594. X        }
  2595. X        return func_string( buf );
  2596. X    case FN_AVAILMEM:
  2597. X        if( ac==1 && !Strcmp(av[0],"chip")) n=MEMF_CHIP;
  2598. X        if( ac==1 && !Strcmp(av[0],"fast")) n=MEMF_FAST;
  2599. X        return func_int( AvailMem( n ));
  2600. X    case FN_CENTER:
  2601. X        if( (n=posatoi( av[1] )) > (l=strlen(av[0])) ) i=(n-l)/2, j=n-i-l;
  2602. X        sprintf( buf, "%*s%s%*s", i,"",av[0], j,"" );
  2603. X        return func_string( buf );
  2604. X    case FN_CHECKPORT:
  2605. X        return func_bool( (int)FindPort( av[0] ) );
  2606. X    case FN_GETCLASS:
  2607. X        if( str=getclass(av[0]) )
  2608. X            if( str=index(strncpy( buf,str,100 ),0xA0) )
  2609. X                *str=0;
  2610. X        return func_string(buf);
  2611. X    case FN_COMPLETE:
  2612. X        for( i=1, l=strlen(av[0]); i<ac; i++ )
  2613. X            if( !Strncmp( av[0], av[i], l ) )
  2614. X                { str=av[i]; break; }
  2615. X        return func_string( str );
  2616. X    case FN_CONCAT:
  2617. X        return func_string( compile_av( av, 0, ac, ' ', 1));
  2618. X    case FN_CONFIRM:
  2619. X        for( i=1, get++, confirmed=0; i<ac; i++ )
  2620. X            if( confirm( av[0], av[i]) )
  2621. X                *get++=av[i];
  2622. X        return func_array( av+1, (get-av)-1 );
  2623. X    case FN_CONSOLE:
  2624. X        if( !strcmp(av[0],"STDIN")) i=IsInteractive(Input());
  2625. X        else if( !strcmp(av[0],"STDOUT")) i=IsInteractive(Output());
  2626. X        return func_bool(i);
  2627. X    case FN_DECTOHEX:
  2628. X        sprintf( buf, "%x", unlatoi( av[0] ));
  2629. X        return func_string( buf );
  2630. X    case FN_DELWORDS:
  2631. X        n2=posatoi( av[--ac] ); if( atoierr ) return 20;
  2632. X    case FN_DELWORD:
  2633. X        n=posatoi( av[--ac] )-1;
  2634. X        for( ; i<ac && i<n; i++ ) *av++=*get++;
  2635. X        for( ; i<ac && i<n+n2; i++ ) get++;
  2636. X        for( ; i<ac ; i++ ) *av++=*get++;
  2637. X        return func_array( oldav, av-oldav );
  2638. X    case FN_DIRS:
  2639. X        for( ; --ac>=0; get++ )
  2640. X            if( exists( *get ) && isdir( *get ) )
  2641. X                *av++=*get;
  2642. X        return func_array( oldav, av-oldav );
  2643. X    case FN_DRIVE:
  2644. X        return func_string( drive_name( av[0] ) );
  2645. X    case FN_DRIVES:
  2646. X        get_drives( buf );
  2647. X        return func_string( buf );
  2648. X    case FN_EXISTS:
  2649. X        return func_bool( exists( av[0] ));
  2650. X    case FN_FILEBLKS:
  2651. X        return func_string( info_part( av, ac, 1, buf ) );
  2652. X    case FN_FILELEN:
  2653. X        while( --ac>=0 )
  2654. X            i+=filesize( *av++ );
  2655. X        return func_int( i );
  2656. X    case FN_FILEPROT:
  2657. X        return func_string( info_part( av, ac, 0, buf ) );
  2658. X    case FN_FILEREQ:
  2659. X        return func_string( file_request( av, ac, buf ) );
  2660. X    case FN_FILES:
  2661. X        for( ; --ac>=0; get++ )
  2662. X            if( exists( *get ) && !isdir( *get ) )
  2663. X                *av++=*get;
  2664. X        return func_array( oldav, av-oldav );
  2665. X    case FN_FIRST:
  2666. X        return func_string( av[0] );
  2667. X    case FN_FREEBLKS:
  2668. X        return func_string( oneinfo( av[0], 3 ));
  2669. X    case FN_FREEBYTES:
  2670. X        return func_string( oneinfo( av[0], 2 ));
  2671. X    case FN_FREESTORE:
  2672. X        return func_string( oneinfo( av[0], 4 ));
  2673. X    case FN_HOWMANY:
  2674. X        Getenv( shellctr, buf, 10);
  2675. X        return func_string( buf );
  2676. X    case FN_IOERROR:
  2677. X        return func_string( ioerror( atoi( av[0] )));
  2678. X    case FN_INDEX:
  2679. X        str=strstr( av[0], av[1] );
  2680. X        return func_int( str ? (str-av[0])+1 : 0 );
  2681. X    case FN_INFO:
  2682. X        return func_string( oneinfo( av[0], 1 ));
  2683. X    case FN_INTERSECT:
  2684. X        return wordset( av, ac, and );
  2685. X    case FN_LAST:
  2686. X        return func_string( ac ? av[ac-1] : "" );
  2687. X    case FN_LOOKFOR:
  2688. X        return func_string( dofind( av[0], "", buf, av[1]));
  2689. X    case FN_LOWER:
  2690. X        while( --ac>=0 ) strlwr( *av++ );
  2691. X        return func_array( oldav, av-oldav );
  2692. X    case FN_MATCH:
  2693. X        for( str=av[--ac]; --ac>=0; get++ )
  2694. X            if( compare_ok( str, *get, 0 ) )
  2695. X                *av++=*get;
  2696. X        return func_array( oldav, av-oldav );
  2697. X    case FN_MAX:
  2698. X        for( n=MININT; i<ac; i++ ) 
  2699. X            { if( (j=unlatoi(av[i] )) > n ) n=j; if( atoierr ) return 20; }
  2700. X        return func_int( n );
  2701. X    case FN_MEGS:
  2702. X        return func_string( itok( atoi( av[0] )));
  2703. X    case FN_MEMBER:
  2704. X        for( i=1; i<ac && Strcmp(av[0],av[i]) ; i++ ) ;
  2705. X        return func_bool( ac!=i );
  2706. X    case FN_MIN:
  2707. X        for( n=MAXINT; i<ac; i++ )
  2708. X            { if( (j=unlatoi(av[i] )) < n ) n=j; if( atoierr ) return 20; }
  2709. X        return func_int( n );
  2710. X    case FN_MOUNTED:
  2711. X        get=expand_devs();
  2712. X        for( i=0; (str=get[i]) && Strcmp(str+1,av[0]); i++ ) ;
  2713. X        free_expand(get);
  2714. X        return func_bool((int)str);
  2715. X    case FN_NAMEEXT:
  2716. X        return func_string( rindex(av[0],'.')?rindex(av[0],'.')+1:(char *)NULL);
  2717. X    case FN_NAMEROOT:
  2718. X        if( rindex(av[0],'.') ) *rindex(av[0],'.')=0;
  2719. X        return func_string( av[0] );
  2720. X    case FN_PATHNAME:
  2721. X        str=av[0]+strlen(av[0])-1;
  2722. X        while( str>av[0] && *str!=':' && *str!='/' ) str--;
  2723. X        if( *str==':' ) str++;
  2724. X        *str=0;
  2725. X        return func_string(av[0]);
  2726. X    case FN_PICKARGS:
  2727. X        while( *get && **get=='-' ) get++;
  2728. X        while( *get )  *av++=*get++ ;
  2729. X        return func_array( oldav, av-oldav );
  2730. X    case FN_PICKOPTS:
  2731. X        while( *get && **get=='-' ) *av++=*get++;
  2732. X        return func_array( oldav, av-oldav );
  2733. X    case FN_CLINUM:
  2734. X        return func_int( clinum( av[0] ) );
  2735. X    case FN_RPN:
  2736. X        return func_int( eval_rpn( av, ac, 1 ));
  2737. X    case FN_SORTARGS:
  2738. X        QuickSort( av, ac );
  2739. X        return func_array( av, ac );
  2740. X    case FN_SORTNUM:
  2741. X        DirQuickSort( av, ac, numcmp, 0, 0 );
  2742. X        return func_array( av, ac );
  2743. X    case FN_SPLIT:
  2744. X        return split_arg( av, ac );
  2745. X    case FN_STRCMP:
  2746. X        return func_int( strcmp( av[0], av[1] ) );
  2747. X    case FN_UNION:
  2748. X        return wordset( av, ac, or );
  2749. X    case FN_UNIQUE:
  2750. X        QuickSort( av, ac );
  2751. X        while( *get )
  2752. X            { *av++=*get++; while( *get && !Strcmp(*get,*(get-1)))
  2753. X                get++; }
  2754. X        return func_array( oldav, av-oldav );
  2755. X    case FN_UPPER:
  2756. X        while( --ac>=0 ) strupr( *av++ );
  2757. X        return func_array( oldav, oldac );
  2758. X    case FN_VOLUME:
  2759. X        return func_string( oneinfo( av[0], 5 ));
  2760. X    case FN_WINTOP:
  2761. X        return func_int( Win ? Win->TopEdge : 0 );
  2762. X    case FN_WINLEFT:
  2763. X        return func_int( Win ? Win->LeftEdge: 0 );
  2764. X    case FN_WINHEIGHT:
  2765. X        return func_int( Win ? Win->Height : 0 );
  2766. X    case FN_WINWIDTH:
  2767. X        return func_int( Win ? Win->Width  : 0 );
  2768. X    case FN_WORD:
  2769. X        n2=1; goto wordf;
  2770. X    case FN_SUBWORDS:
  2771. X        n2=posatoi( av[--ac] ); if( atoierr ) return 20;
  2772. X    wordf:
  2773. X        n=posatoi( av[--ac] )-1; if( atoierr ) return 20;
  2774. X        for( i=0; i<ac && i<n; i++ ) get++;
  2775. X        for(    ; i<ac && i<n+n2; i++ ) *av++=*get++;;
  2776. X        return func_array( oldav, av-oldav );
  2777. X    case FN_WITHOUT:
  2778. X        return wordset( av, ac, without );
  2779. X    case FN_WORDS:
  2780. X        return func_int( ac );
  2781. X    }
  2782. X    return func_string( "" );
  2783. X}
  2784. END_OF_FILE
  2785. if test 29350 -ne `wc -c <'comm2.c'`; then
  2786.     echo shar: \"'comm2.c'\" unpacked with wrong size!
  2787. fi
  2788. # end of 'comm2.c'
  2789. fi
  2790. echo shar: End of archive 5 \(of 6\).
  2791. cp /dev/null ark5isdone
  2792. MISSING=""
  2793. for I in 1 2 3 4 5 6 ; do
  2794.     if test ! -f ark${I}isdone ; then
  2795.     MISSING="${MISSING} ${I}"
  2796.     fi
  2797. done
  2798. if test "${MISSING}" = "" ; then
  2799.     echo You have unpacked all 6 archives.
  2800.     rm -f ark[1-9]isdone
  2801. else
  2802.     echo You still need to unpack the following archives:
  2803.     echo "        " ${MISSING}
  2804. fi
  2805. ##  End of shell archive.
  2806. exit 0
  2807. -- 
  2808. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2809. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2810. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2811.